Home > Enterprise >  Change shape of a button with custom svg
Change shape of a button with custom svg

Time:04-28

I have a website with a carousel sliders library. The thing is, each slider has a button circle-shaped with border radius and when I click one button I assign it the 'active' class, so when is active I make the button bigger. But I want to change it's shape too, to make it look like a star. I thought that putting an svg with clipPath would make the trick, but I didn't work. If anyone could tell me how to make it change it's shape, if it's any library or something, it would help me a lot.

Here's what I tried:

<button>
    <svg >
        <defs>
            <clipPath id="clipStar">
                <path  id="star2" d="M325.07,30.69l80.91,163.95l180.93,26.29c18.09,2.63,25.31,24.86,12.22,37.62L468.22,386.16l30.91,180.2
                c3.09,18.02-15.82,31.76-32,23.25l-161.83-85.08l-161.83,85.08c-16.18,8.51-35.09-5.23-32-23.25l30.91-180.2L11.45,258.55
                c-13.09-12.76-5.87-34.99,12.22-37.62l180.93-26.29l80.91-163.95C293.61,14.3,316.98,14.3,325.07,30.69z"/>
            </clipPath>
        </defs>
    </svg>
</button>

And wanted to style it this way:

button {
    width: 0.8em;
    height: 0.8em;
    border: none;
    border-radius: 50%;
    transition: 0.2s ease-out;
    position: relative;
    clip-path: url('#clipStar');

    .star2svg {
        position: absolute;
        left: 0;
        right: 0;
        display: block;
        width: 100%;
        height: 100%;
    }
}

CodePudding user response:

The svg element needs a viewBox to know where to start displaying the content and where to clip it.

In this case, your viewBox is about 650x650:

.star2svg {
  width: 25px;
}
<button>
    <svg  viewBox="0 0 650 650">
        <path d="M325.07,30.69l80.91,163.95l180.93,26.29c18.09,2.63,25.31,24.86,12.22,37.62L468.22,386.16l30.91,180.2 c3.09,18.02-15.82,31.76-32,23.25l-161.83-85.08l-161.83,85.08c-16.18,8.51-35.09-5.23-32-23.25l30.91-180.2L11.45,258.55
                c-13.09-12.76-5.87-34.99,12.22-37.62l180.93-26.29l80.91-163.95C293.61,14.3,316.98,14.3,325.07,30.69z"></path>
    </svg>
</button>




[Edit following comment]

If you want the button to be the same shape as the star, the best solution is either make the button transparent, or get rid of the <button> element and watch the svg click event

.myButton {
    background: none;
    border: none;
}

.star2svg {
    width: 25px;
}
<p>Transparent button (click to alert)</p>
<button  onclick="alert('button clicked')">
    <svg  viewBox="0 0 650 650">
        <path d="M325.07,30.69l80.91,163.95l180.93,26.29c18.09,2.63,25.31,24.86,12.22,37.62L468.22,386.16l30.91,180.2 c3.09,18.02-15.82,31.76-32,23.25l-161.83-85.08l-161.83,85.08c-16.18,8.51-35.09-5.23-32-23.25l30.91-180.2L11.45,258.55
                c-13.09-12.76-5.87-34.99,12.22-37.62l180.93-26.29l80.91-163.95C293.61,14.3,316.98,14.3,325.07,30.69z"></path>
    </svg>
</button>

<br/>

<p>SVG onClick event (click to alert)</p>
<svg  viewBox="0 0 650 650" onclick="alert('svg clicked')">
    <path d="M325.07,30.69l80.91,163.95l180.93,26.29c18.09,2.63,25.31,24.86,12.22,37.62L468.22,386.16l30.91,180.2 c3.09,18.02-15.82,31.76-32,23.25l-161.83-85.08l-161.83,85.08c-16.18,8.51-35.09-5.23-32-23.25l30.91-180.2L11.45,258.55
            c-13.09-12.76-5.87-34.99,12.22-37.62l180.93-26.29l80.91-163.95C293.61,14.3,316.98,14.3,325.07,30.69z"></path>
</svg>

CodePudding user response:

You could swap/transition the svg path shape via css path() function.

For transitions/morphing you need both shapes to have the exact same number of commands. Css tricks: Animate SVG Path Changes in CSS

Transitioning between a circle and a star could be done by:

  • reducing the star path to a polygon with 10 points
  • rounded corners are achieved by stroke-linecaps/stroke-linejoin properties
  • the initial circle shape is created by centering all 10 points to the center applying a larger stroke-width: M50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1z

Example

.btn {
  appearance: none;
  -webkit-appearance: none;
  font-size: 10vw;
  background: none;
  padding: 0;
  border: none;
  color: #000;
  cursor: pointer;
}

.btnSvg {
  display: inline-block;
  height: 1em;
}

.btn .btnSvgPath {
  transition: 0.3s;
  border: none;
  stroke-width: 75;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.btn:hover .btnSvgPath {
  d: path('M50,77L23.3,91l5.1-29.7l-21.6-21L36.7,36L50,9l13.3,27l29.8,4.3l-21.6,21L76.7,91L50,77z');
  stroke-width: 5;
  color: gold;
}
<button >
    <svg  viewBox="0 0 100 100" >
        <path  d="M50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1L50,53.1z" fill="currentColor" stroke="currentColor" />
    </svg>
</button>

  • Related