Skip to content

Instantly share code, notes, and snippets.

@pierreburel
Created February 17, 2023 05:15
Show Gist options
  • Save pierreburel/b893f519b54e7e73aabf640732f7938b to your computer and use it in GitHub Desktop.
Save pierreburel/b893f519b54e7e73aabf640732f7938b 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;
$preset-gentle: (
mass: 1,
stiffness: 100,
damping: 15,
);
$preset-quick: (
mass: 1,
stiffness: 300,
damping: 20,
);
$preset-bouncy: (
mass: 1,
stiffness: 600,
damping: 15,
);
$preset-slow: (
mass: 1,
stiffness: 80,
damping: 20,
);
@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.pow(math.$e, -$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;
}
@function remove-consecutive-values($keyframes) {
$last: ();
$before-last: ();
@each $keyframe, $properties in $keyframes {
@each $property, $value in $properties {
@if map.get($last, $property, value) == $value and map.get($before-last, $property, value) == $value {
$keyframes: map.deep-remove($keyframes, map.get($last, $property, keyframe), $property);
}
$before-last: map.set($before-last, $property, map.get($last, $property));
$last: map.set($last, $property, (keyframe: $keyframe, value: $value));
}
}
@return $keyframes;
}
$transforms: ('translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'perspective');
@mixin keyframes($name, $properties, $steps: 50, $args...) {
$keyframes: ();
@for $i from 0 through $steps {
$percentage: $i * 100 / $steps + '%';
$keyframe: ();
$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 {
$keyframe: map.set($keyframe, $property, $value);
}
}
$keyframe: map.set($keyframe, transform, string.slice(string.unquote($transform), 2, -1));
$keyframes: map.set($keyframes, $percentage, $keyframe);
}
@keyframes #{$name} {
@each $keyframe, $properties in remove-consecutive-values($keyframes) {
#{$keyframe} {
@each $property, $value in $properties {
#{$property}: $value;
}
}
}
}
}
$properties: (
opacity: (0, 1),
translateX: (0%, 100%),
rotate: (0deg, 1turn),
scale: (1, 1.5),
);
@include keyframes(test1, $properties);
@include keyframes(test2, $properties, $preset-slow...);
div {
width: 100px;
height: 100px;
animation-timing-function: linear;
animation-duration: 1s;
animation-fill-mode: both;
&:first-child {
background: red;
:hover & {
animation-name: test1;
}
}
&:last-child {
background: blue;
:hover & {
animation-name: test2;
}
}
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 100vh;
margin: 0;
}
<div></div>
<div></div>
@keyframes test1 {
0% {
opacity: 0;
transform: translateX(0%) rotate(0deg) scale(1);
}
2% {
opacity: 0;
transform: translateX(1.8%) rotate(6.5deg) scale(1);
}
4% {
opacity: 0.1;
transform: translateX(6.5%) rotate(23.5deg) scale(1);
}
6% {
opacity: 0.1;
transform: translateX(13.2%) rotate(47.7deg) scale(1.1);
}
8% {
opacity: 0.2;
transform: translateX(21.2%) rotate(76.4deg) scale(1.1);
}
10% {
opacity: 0.3;
transform: translateX(29.8%) rotate(107.4deg) scale(1.1);
}
12% {
opacity: 0.4;
transform: translateX(38.6%) rotate(139deg) scale(1.2);
}
14% {
opacity: 0.5;
transform: translateX(47.3%) rotate(170.1deg) scale(1.2);
}
16% {
opacity: 0.6;
transform: translateX(55.5%) rotate(199.7deg) scale(1.3);
}
18% {
opacity: 0.6;
transform: translateX(63.1%) rotate(227.1deg) scale(1.3);
}
20% {
opacity: 0.7;
transform: translateX(70%) rotate(252deg) scale(1.3);
}
22% {
opacity: 0.8;
transform: translateX(76.2%) rotate(274.2deg) scale(1.4);
}
24% {
opacity: 0.8;
transform: translateX(81.5%) rotate(293.5deg) scale(1.4);
}
26% {
opacity: 0.9;
transform: translateX(86.2%) rotate(310.2deg) scale(1.4);
}
28% {
transform: translateX(90.1%) rotate(324.2deg) scale(1.5);
}
30% {
opacity: 0.9;
transform: translateX(93.3%) rotate(335.8deg) scale(1.5);
}
32% {
opacity: 1;
transform: translateX(95.9%) rotate(345.3deg) scale(1.5);
}
34% {
transform: translateX(98%) rotate(352.8deg) scale(1.5);
}
36% {
transform: translateX(99.6%) rotate(358.6deg) scale(1.5);
}
38% {
transform: translateX(100.8%) rotate(363deg) scale(1.5);
}
40% {
transform: translateX(101.7%) rotate(366.1deg) scale(1.5);
}
42% {
transform: translateX(102.3%) rotate(368.2deg) scale(1.5);
}
44% {
transform: translateX(102.6%) rotate(369.5deg) scale(1.5);
}
46% {
transform: translateX(102.8%) rotate(370.1deg) scale(1.5);
}
48% {
transform: translateX(102.8%) rotate(370.2deg) scale(1.5);
}
50% {
transform: translateX(102.8%) rotate(369.9deg) scale(1.5);
}
52% {
transform: translateX(102.6%) rotate(369.4deg) scale(1.5);
}
54% {
transform: translateX(102.4%) rotate(368.7deg) scale(1.5);
}
56% {
transform: translateX(102.2%) rotate(367.8deg) scale(1.5);
}
58% {
transform: translateX(101.9%) rotate(366.9deg) scale(1.5);
}
60% {
transform: translateX(101.7%) rotate(366deg) scale(1.5);
}
62% {
transform: translateX(101.4%) rotate(365.2deg) scale(1.5);
}
64% {
transform: translateX(101.2%) rotate(364.3deg) scale(1.5);
}
66% {
transform: translateX(101%) rotate(363.6deg) scale(1.5);
}
68% {
transform: translateX(100.8%) rotate(362.9deg) scale(1.5);
}
70% {
transform: translateX(100.6%) rotate(362.3deg) scale(1.5);
}
72% {
transform: translateX(100.5%) rotate(361.8deg) scale(1.5);
}
74% {
transform: translateX(100.4%) rotate(361.3deg) scale(1.5);
}
76% {
transform: translateX(100.3%) rotate(360.9deg) scale(1.5);
}
78% {
transform: translateX(100.2%) rotate(360.6deg) scale(1.5);
}
80% {
transform: translateX(100.1%) rotate(360.4deg) scale(1.5);
}
82% {
transform: translateX(100%) rotate(360.2deg) scale(1.5);
}
84% {
transform: translateX(100%) rotate(360deg) scale(1.5);
}
86% {
transform: translateX(100%) rotate(359.9deg) scale(1.5);
}
88% {
transform: translateX(99.9%) rotate(359.8deg) scale(1.5);
}
90% {
transform: translateX(99.9%) rotate(359.8deg) scale(1.5);
}
92% {
transform: translateX(99.9%) rotate(359.7deg) scale(1.5);
}
98% {
transform: translateX(99.9%) rotate(359.7deg) 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);
}
2% {
opacity: 0;
transform: translateX(1.4%) rotate(5.1deg) scale(1);
}
4% {
opacity: 0.1;
transform: translateX(5.1%) rotate(18.2deg) scale(1);
}
6% {
opacity: 0.1;
transform: translateX(10.2%) rotate(36.5deg) scale(1.1);
}
8% {
opacity: 0.2;
transform: translateX(16.1%) rotate(58deg) scale(1.1);
}
10% {
opacity: 0.2;
transform: translateX(22.5%) rotate(81.2deg) scale(1.1);
}
12% {
opacity: 0.3;
transform: translateX(29.1%) rotate(104.8deg) scale(1.1);
}
14% {
opacity: 0.4;
transform: translateX(35.6%) rotate(128.2deg) scale(1.2);
}
16% {
opacity: 0.4;
transform: translateX(41.9%) rotate(150.8deg) scale(1.2);
}
18% {
opacity: 0.5;
transform: translateX(47.8%) rotate(172.2deg) scale(1.2);
}
20% {
opacity: 0.5;
transform: translateX(53.4%) rotate(192.2deg) scale(1.3);
}
22% {
opacity: 0.6;
transform: translateX(58.5%) rotate(210.7deg) scale(1.3);
}
24% {
opacity: 0.6;
transform: translateX(63.2%) rotate(227.6deg) scale(1.3);
}
26% {
opacity: 0.7;
transform: translateX(67.5%) rotate(243deg) scale(1.3);
}
28% {
transform: translateX(71.4%) rotate(256.9deg) scale(1.4);
}
30% {
opacity: 0.7;
transform: translateX(74.8%) rotate(269.4deg) scale(1.4);
}
32% {
opacity: 0.8;
transform: translateX(77.9%) rotate(280.5deg) scale(1.4);
}
34% {
transform: translateX(80.7%) rotate(290.5deg) scale(1.4);
}
36% {
opacity: 0.8;
transform: translateX(83.1%) rotate(299.3deg) scale(1.4);
}
38% {
opacity: 0.9;
transform: translateX(85.3%) rotate(307.1deg) scale(1.4);
}
40% {
transform: translateX(87.2%) rotate(314deg) scale(1.4);
}
42% {
transform: translateX(88.9%) rotate(320deg) scale(1.4);
}
44% {
transform: translateX(90.4%) rotate(325.3deg) scale(1.5);
}
46% {
transform: translateX(91.6%) rotate(329.9deg) scale(1.5);
}
48% {
transform: translateX(92.8%) rotate(334deg) scale(1.5);
}
50% {
transform: translateX(93.7%) rotate(337.5deg) scale(1.5);
}
52% {
opacity: 0.9;
transform: translateX(94.6%) rotate(340.6deg) scale(1.5);
}
54% {
opacity: 1;
transform: translateX(95.3%) rotate(343.2deg) scale(1.5);
}
56% {
transform: translateX(96%) rotate(345.6deg) scale(1.5);
}
58% {
transform: translateX(96.5%) rotate(347.6deg) scale(1.5);
}
60% {
transform: translateX(97%) rotate(349.3deg) scale(1.5);
}
62% {
transform: translateX(97.4%) rotate(350.8deg) scale(1.5);
}
64% {
transform: translateX(97.8%) rotate(352.1deg) scale(1.5);
}
66% {
transform: translateX(98.1%) rotate(353.2deg) scale(1.5);
}
68% {
transform: translateX(98.4%) rotate(354.2deg) scale(1.5);
}
70% {
transform: translateX(98.6%) rotate(355deg) scale(1.5);
}
72% {
transform: translateX(98.8%) rotate(355.7deg) scale(1.5);
}
74% {
transform: translateX(99%) rotate(356.3deg) scale(1.5);
}
76% {
transform: translateX(99.1%) rotate(356.9deg) scale(1.5);
}
78% {
transform: translateX(99.3%) rotate(357.3deg) scale(1.5);
}
80% {
transform: translateX(99.4%) rotate(357.7deg) scale(1.5);
}
82% {
transform: translateX(99.5%) rotate(358deg) scale(1.5);
}
84% {
transform: translateX(99.5%) rotate(358.3deg) scale(1.5);
}
86% {
transform: translateX(99.6%) rotate(358.6deg) scale(1.5);
}
88% {
transform: translateX(99.7%) rotate(358.8deg) scale(1.5);
}
90% {
transform: translateX(99.7%) rotate(359deg) scale(1.5);
}
92% {
transform: translateX(99.8%) rotate(359.1deg) scale(1.5);
}
94% {
transform: translateX(99.8%) rotate(359.2deg) scale(1.5);
}
96% {
transform: translateX(99.8%) rotate(359.4deg) scale(1.5);
}
98% {
transform: translateX(99.8%) rotate(359.5deg) scale(1.5);
}
100% {
opacity: 1;
transform: translateX(100%) rotate(1turn) scale(1.5);
}
}
div {
width: 100px;
height: 100px;
animation-timing-function: linear;
animation-duration: 1s;
animation-fill-mode: both;
}
div:first-child {
background: red;
}
:hover div:first-child {
animation-name: test1;
}
div:last-child {
background: blue;
}
:hover div:last-child {
animation-name: test2;
}
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
height: 100vh;
margin: 0;
}
{
"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