From our sponsor: Meco is a distraction-free space for reading and discovering newsletters, separate from the inbox.
After playing with some on-scroll morphing background shapes, we wanted to explore some hover effects in this demo. By morphing SVG paths we can create some organic, flowy movements on hover. Doing so on an SVG clipPath
allows us to use this effect on an image.
For the animations in this demo we are using anime.js.
For the hover effect on an item, we are doing several things. Let’s just look at the actual shape manipulations we do. These are performed on the clip path, the image that is being clipped and a decorative path element that is behind the image.
Here is an example item:
<div class="item item--style-1"
data-animation-path-duration="800"
data-animation-path-easing="easeInOutCubic"
data-path-elasticity="300"
data-morph-path="M 189,80.37 C 232.6,46.67 352.5,67.06 350.9,124.1 349.5,173.4 311.7,168 312.4,248.1 312.9,301.1 382.5,319.2 368.5,379.1 349.4,460.6 137.7,467.5 117.6,386.3 98.68,309.7 171.5,292.2 183.6,240.1 195.7,188.2 123.8,130.7 189,80.37 Z"
data-path-scaleX="0.8"
data-path-scaleY="1.1"
data-path-translateX="0"
data-path-translateY="30"
data-path-rotate="5"
data-animation-image-duration="800"
data-animation-image-easing="easeInOutQuart"
data-image-elasticity="300"
data-image-scaleX="1.2"
data-image-scaleY="1.2"
data-image-translateX="-20"
data-image-translateY="-45"
data-image-rotate="-5"
data-animation-deco-duration="1300"
data-animation-deco-easing="easeOutQuad"
data-deco-elasticity="300"
data-deco-scaleX="0.8"
data-deco-scaleY="0.9"
data-deco-translateX="-5"
data-deco-translateY="-5"
data-deco-rotate="2">
<svg class="item__svg" width="500px" height="500px" viewBox="0 0 500 500">
<clipPath id="clipShape1">
<path class="item__clippath" d="M 189,80.37 C 243,66.12 307.3,87.28 350.9,124.1 389.3,156.6 417,211.2 418.1,263.4 419.1,305.7 401.8,355.6 368.5,379.1 298.8,428 179.2,446.4 117.6,386.3 65.4,335.3 78.55,230.3 105.5,160.5 119.7,123.6 152.6,89.85 189,80.37 Z" />
</clipPath>
<g class="item__deco">
<use xlink:href="#deco1" />
</g>
<g clip-path="url(#clipShape1)">
<image class="item__img" xlink:href="img/1.png" x="0" y="0" height="500px" width="500px" />
</g>
</svg>
<div class="item__meta">
<div class="item__number">
<span class="item__specimen">21</span>
<span class="item__reference">BX3</span>
</div>
<h2 class="item__title">Codium fasciculatus</h2>
<h3 class="item__subtitle">Exoplanet Gliese 180 b</h3>
</div>
</div>
We are using a clipPath
on an image
in the SVG. The deco element is taken from outside; we’ve included all of the paths at the beginning of the HTML file and reference to them with use
. You can also directly add it as well, but it allows for re-use which in our case makes sense. The path that the initial clip path will morph to is stored in the data-morph-path data attribute. The other data attributes are for setting the durations, easings, etc. for the path, the image and the deco element. The only one missing here is the delay, which you can also add for each of the elements. Of course you don’t have to specify all these data attributes as there are default values for each one of them (see main.js).
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
We hope you enjoy this little effect and find it useful!
References and Credits
- Anime.js by Julian Garnier
- Images made with digiful’s Oil Spill – Marble Styles
Refreshing ! Nice work.
Very cute….I made it work. Now I just need to figure out how to have links to those blobs.
Thanks ps link to anime.js is broken
Thank you! Updated! Cheers, ML
Phenomenal work! Looks like I’ve got a weekend project now. Thank you for this breath of fresh air!
impressive! very cool effect..but it could more beautiful if you would have add parallax effect too. Nice work
You are just awesome, i wish i was half as good. REALLY!!!
Nice effects!
Can someone tell me how can I trigger the effect with JavaScript or jQuery?
I was trying to do something like the code below, but it didn’t workout. Thanks.
$(document).scroll(function () {
if($(window).scrollTop() > 100){
$(‘.item’).trigger(‘mouseenter’);
else{
$(‘.item’).trigger(‘mouseleave’);
}
});