From our sponsor: Chromatic - Visual testing for Storybook, Playwright & Cypress. Catch UI bugs before your users do.
Today we’d like to share some inspiration for card effects with you. The idea is to animate the top element of a stack by clicking on an accept or reject button. We’ve used this Tinder-like example to show some symmetric and complementing pairs of effects, but these kind of animations can fit into many scenarios involving all kinds of card stacks that don’t necessarily have a dual logic.
The markup for a stack and its controls looks like this:
<ul id="stack_yuda" class="stack stack--yuda">
<li class="stack__item"><img src="img/1.png" alt="Tree 1" /></li>
<li class="stack__item"><img src="img/2.png" alt="Tree 2" /></li>
<li class="stack__item"><img src="img/3.png" alt="Tree 3" /></li>
<li class="stack__item"><img src="img/4.png" alt="Tree 4" /></li>
<li class="stack__item"><img src="img/5.png" alt="Tree 5" /></li>
<li class="stack__item"><img src="img/6.png" alt="Tree 6" /></li>
</ul>
<div class="controls">
<button class="button button--sonar button--reject" data-stack="stack_yuda">
<i class="fa fa-times"></i>
<span class="text-hidden">Reject</span>
</button>
<button class="button button--sonar button--accept" data-stack="stack_yuda">
<i class="fa fa-check"></i>
<span class="text-hidden">Accept</span>
</button>
</div>
With all the stack items positioned absolutely on top of each other, we apply a “accept” or “reject” class to the current item, depending on which button we clicked.
Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.
For this demo we’ve implemented a little plugin that takes care of the functionality. We use dynamics.js by Michael Villar as animation library. The animations for moving the items away (accept/reject) are defined as CSS animations in the stylesheet.
The plugin has the following options:
Stack.prototype.options = {
// stack's perspective value
perspective: 1000,
// stack's perspective origin
perspectiveOrigin : '50% -50%',
// number of visible items in the stack
visible : 3,
// infinite navigation
infinite : true,
// callback: when reaching the end of the stack
onEndStack : function() {return false;},
// animation settings for the items' movements in the stack when the items rearrange
// object that is passed to the dynamicsjs animate function (see more at http://dynamicsjs.com/)
// example:
// {type: dynamics.spring,duration: 1641,frequency: 557,friction: 459,anticipationSize: 206,anticipationStrength: 392}
stackItemsAnimation : {
duration : 500,
type : dynamics.bezier,
points : [{'x':0,'y':0,'cp':[{'x':0.25,'y':0.1}]},{'x':1,'y':1,'cp':[{'x':0.25,'y':1}]}]
},
// delay for the items' rearrangement / delay before stackItemsAnimation is applied
stackItemsAnimationDelay : 0,
// animation settings for the items' movements in the stack before the rearrangement
// we can set up different settings depending on whether we are approving or rejecting an item
stackItemsPreAnimation : {
reject : {
// if true, then the settings.properties parameter will be distributed through the items in a non equal fashion
// for instance, if we set settings.properties = {translateX:100} and we have options.visible = 4,
// then the second item in the stack will translate 100px, the second one 75px and the third 50px
elastic : true,
// object that is passed into the dynamicsjs animate function - second parameter - (see more at http://dynamicsjs.com/)
animationProperties : {},
// object that is passed into the dynamicsjs animate function - third parameter - (see more at http://dynamicsjs.com/)
animationSettings : {}
},
accept : {
// if true, then the settings.properties parameter will be distributed through the items in a non equal fashion
// for instance, if we set settings.properties = {translateX:100} and we have options.visible = 4,
// then the second item on the stack will translate 100px, the second one 75px and the third 50px
elastic : true,
// object that is passed into the dynamicsjs animate function - second parameter - (see more at http://dynamicsjs.com/)
animationProperties : {},
// object that is passed into the dynamicsjs animate function (see more at http://dynamicsjs.com/)
animationSettings : {}
}
}
}
And this is an example for the reject/accept action effect:
/***********************************************/
/******************** yuda *********************/
/***********************************************/
.stack--yuda .stack__item--reject {
-webkit-animation: yudaReject 0.5s forwards;
animation: yudaReject 0.5s forwards;
}
@-webkit-keyframes yudaReject {
to {
opacity: 0;
-webkit-transform: translate3d(0, 200px, 0);
transform: translate3d(0, 200px, 0);
}
}
@keyframes yudaReject {
to {
opacity: 0;
-webkit-transform: translate3d(0, 200px, 0);
transform: translate3d(0, 200px, 0);
}
}
.stack--yuda .stack__item--accept {
-webkit-transform-origin: 50% 300%;
transform-origin: 50% 300%;
-webkit-animation: yudaAccept 0.5s forwards;
animation: yudaAccept 0.5s forwards;
}
@-webkit-keyframes yudaAccept {
to {
opacity: 0;
-webkit-transform: rotate3d(0, 0, 1, 20deg);
transform: rotate3d(0, 0, 1, 20deg);
}
}
@keyframes yudaAccept {
to {
opacity: 0;
-webkit-transform: rotate3d(0, 0, 1, 20deg);
transform: rotate3d(0, 0, 1, 20deg);
}
}
The tree vectors used in the demo are from Freepic and you can find them here: Tree vector designed by Freepik
We hope you have fun with these effects and find them inspirational!
Very cool experiments.
Anyway, did you use indonesian names for each ideas?
LOL, I just wonderer if its contain Indonesian name, good job Marry Lou
Great! This is what I am looking for. Thanks!
Indonesian names?
Another amazing work.
How hard would it be to add touch interaction so you could trigger action by pulling to left or right – ala tinder?
Not that hard. You can use jQuery for the swipe interaction.
And when it is swiped in either direction, you can use an event handler to fire the above code.
ahhh. I was thinking how to apply this technique and there you go! Tinder!
Cool effects. I like how some of them jiggle. 🙂
Hello, Can anyone tell me the relation between dynaminc.js and main.js xO
I’ll be very preciate
Thanks for sharing.
Pretty cool, but I’d say one of their weaker demos.
I have en error “Stack is not defined”. Could you please do more detail tutorial how to include this project?
Any idea of how to add a “back” function?
Hi! Did you find a solution to make the back function? I’ve been trying and could make reed the previous item and show it, but with the no right the effects and position (translate). I can’t really find where make this settings.
Hi, all material in your page is very interesting, but this material have any licence class ? Can I use it in my projects ? should I to pay for use it ? Thanks a lot.
How hard could be add a previous button? Because now this example is just for show next elements.
Any idea? Thanks!
Cool! You did it again! Thanks!