Skip to content

Instantly share code, notes, and snippets.

@pierreburel
Created February 17, 2023 03:29
Show Gist options
  • Save pierreburel/1026cb32e8ce0bf1c030f4951f21da9a to your computer and use it in GitHub Desktop.
Save pierreburel/1026cb32e8ce0bf1c030f4951f21da9a to your computer and use it in GitHub Desktop.
Generated by SassMeister.com.
@use "sass:list";
@use "sass:map";
@use "sass:math";
@use "sass:string";
$mass: 1 !default;
$stiffness: 100 !default;
$damping: 15 !default;
@function spring($t, $mass: $mass, $stiffness: $stiffness, $damping: $damping) {
$w0: math.sqrt($stiffness / $mass);
$zeta: $damping / (2 * math.sqrt($stiffness * $mass));
$wd: if($zeta < 1, $w0 * math.sqrt(1 - $zeta * $zeta), 0);
$a: 1;
$b: if($zeta < 1, $zeta * $w0 / $wd, $w0);
@if $zeta < 1 {
@return 1 - math.pow(math.$e, -$t * $zeta * $w0) * ($a * math.cos($wd * $t) + $b * math.sin($wd * $t));
}
@return 1 - ($a + $b * $t) * math.exp(-$t * $w0);
}
@function lerp($from, $to, $t) {
@return $from * (1 - $t) + $to * $t;
}
@function precision($float, $digits: 1) {
$pow: math.pow(10, $digits);
@return round($float * $pow) / $pow;
}
$transforms: ('translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'perspective');
@mixin keyframes($name, $properties, $steps: 100, $args...) {
@keyframes #{$name} {
@for $i from 0 through $steps {
#{($i * 100 / $steps + '%')} {
$transform: '';
@each $property, $values in $properties {
$from: list.nth($values, 1);
$to: list.nth($values, 2);
$value: if($i == 0, $from, if($i == $steps, $to, precision(lerp($from, $to, spring($i / $steps, $args...)))));
@if list.index($transforms, $property) {
$transform: "#{$transform} #{$property}(#{$value})";
} @else {
#{$property}: $value;
}
}
transform: string.slice(string.unquote($transform), 2, -1);
}
}
}
}
$properties: (
opacity: (0, 1),
translateX: (0%, 100%),
rotate: (0deg, 1turn),
scale: (1, 1.5),
);
@include keyframes(test1, $properties);
@include keyframes(test2, $properties, $steps: 10);
div {
background: red;
width: 100px;
height: 100px;
animation-timing-function: linear;
animation-duration: 1s;
animation-fill-mode: both;
:hover &:first-child {
animation-name: test1;
}
:hover &:last-child {
animation-name: test2;
}
}
<div></div>
<div></div>
@keyframes test1 {
0% {
opacity: 0;
transform: translateX(0%) rotate(0deg) scale(1);
}
10% {
opacity: 0.3;
transform: translateX(29.8%) rotate(107.4deg) scale(1.1);
}
20% {
opacity: 0.7;
transform: translateX(70%) rotate(252deg) scale(1.3);
}
30% {
opacity: 0.9;
transform: translateX(93.3%) rotate(335.8deg) scale(1.5);
}
40% {
opacity: 1;
transform: translateX(101.7%) rotate(366.1deg) scale(1.5);
}
50% {
opacity: 1;
transform: translateX(102.8%) rotate(369.9deg) scale(1.5);
}
60% {
opacity: 1;
transform: translateX(101.7%) rotate(366deg) scale(1.5);
}
70% {
opacity: 1;
transform: translateX(100.6%) rotate(362.3deg) scale(1.5);
}
80% {
opacity: 1;
transform: translateX(100.1%) rotate(360.4deg) scale(1.5);
}
90% {
opacity: 1;
transform: translateX(99.9%) rotate(359.8deg) scale(1.5);
}
100% {
opacity: 1;
transform: translateX(100%) rotate(1turn) scale(1.5);
}
}
@keyframes test2 {
0% {
opacity: 0;
transform: translateX(0%) rotate(0deg) scale(1);
}
10% {
opacity: 0.3;
transform: translateX(29.8%) rotate(107.4deg) scale(1.1);
}
20% {
opacity: 0.7;
transform: translateX(70%) rotate(252deg) scale(1.3);
}
30% {
opacity: 0.9;
transform: translateX(93.3%) rotate(335.8deg) scale(1.5);
}
40% {
opacity: 1;
transform: translateX(101.7%) rotate(366.1deg) scale(1.5);
}
50% {
opacity: 1;
transform: translateX(102.8%) rotate(369.9deg) scale(1.5);
}
60% {
opacity: 1;
transform: translateX(101.7%) rotate(366deg) scale(1.5);
}
70% {
opacity: 1;
transform: translateX(100.6%) rotate(362.3deg) scale(1.5);
}
80% {
opacity: 1;
transform: translateX(100.1%) rotate(360.4deg) scale(1.5);
}
90% {
opacity: 1;
transform: translateX(99.9%) rotate(359.8deg) scale(1.5);
}
100% {
opacity: 1;
transform: translateX(100%) rotate(1turn) scale(1.5);
}
}
div {
background: red;
width: 100px;
height: 100px;
animation-timing-function: linear;
animation-duration: 1s;
animation-fill-mode: both;
}
:hover div:first-child {
animation-name: test1;
}
:hover div:last-child {
animation-name: test2;
}
{
"sass": {
"compiler": "dart-sass/1.32.12",
"extensions": {},
"syntax": "SCSS",
"outputStyle": "expanded"
},
"autoprefixer": false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment