encre_css/plugins/transition/animation/
mod.rs1#![doc = include_str!("README.md")]
2#![doc(alias = "transition")]
3use crate::prelude::build_plugin::*;
4
5const SPIN_ANIMATION: &str = "@-webkit-keyframes spin {
6 to {
7 transform: rotate(360deg);
8 }
9}
10
11@keyframes spin {
12 from {
13 transform: rotate(0deg);
14 }
15 to {
16 transform: rotate(360deg);
17 }
18}\n\n";
19
20const PING_ANIMATION: &str = "@-webkit-keyframes ping {
21 75%, 100% {
22 transform: scale(2);
23 opacity: 0;
24 }
25}
26
27@keyframes ping {
28 75%, 100% {
29 transform: scale(2);
30 opacity: 0;
31 }
32}\n\n";
33
34const PULSE_ANIMATION: &str = "@-webkit-keyframes pulse {
35 50% {
36 opacity: .5;
37 }
38}
39
40@keyframes pulse {
41 0%, 100% {
42 opacity: 1;
43 }
44 50% {
45 opacity: .5;
46 }
47}\n\n";
48
49const BOUNCE_ANIMATION: &str = "@-webkit-keyframes bounce {
50 0%, 100% {
51 transform: translateY(-25%);
52 -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
53 animation-timing-function: cubic-bezier(0.8,0,1,1);
54 }
55
56 50% {
57 transform: none;
58 -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
59 animation-timing-function: cubic-bezier(0,0,0.2,1);
60 }
61}
62
63@keyframes bounce {
64 0%, 100% {
65 transform: translateY(-25%);
66 -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
67 animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
68 }
69 50% {
70 transform: translateY(0);
71 -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
72 animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
73 }
74}\n\n";
75
76#[derive(Debug)]
77pub(crate) struct PluginDefinition;
78
79impl Plugin for PluginDefinition {
80 fn needs_wrapping(&self) -> bool {
81 false
82 }
83
84 fn can_handle(&self, context: ContextCanHandle) -> bool {
85 match context.modifier {
86 Modifier::Builtin { value, .. } => {
87 ["spin", "ping", "pulse", "bounce", "none"].contains(value)
88 }
89 Modifier::Arbitrary { value, .. } => is_matching_all(value),
90 }
91 }
92
93 fn handle(&self, context: &mut ContextHandle) {
94 match context.modifier {
95 Modifier::Builtin { value, .. } => {
96 let animation = match *value {
97 "none" => "none",
98 "spin" => {
99 context.buffer.raw(SPIN_ANIMATION);
100 "spin 1s linear infinite"
101 }
102 "ping" => {
103 context.buffer.raw(PING_ANIMATION);
104 "ping 1s cubic-bezier(0, 0, 0.2, 1) infinite"
105 }
106 "pulse" => {
107 context.buffer.raw(PULSE_ANIMATION);
108 "pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite"
109 }
110 "bounce" => {
111 context.buffer.raw(BOUNCE_ANIMATION);
112 "bounce 1s infinite"
113 }
114 _ => unreachable!(),
115 };
116
117 generate_wrapper(context, |context| {
118 context.buffer.lines([
119 format_args!("-webkit-animation: {animation};"),
120 format_args!("animation: {animation};"),
121 ]);
122 });
123 }
124 Modifier::Arbitrary { value, .. } => generate_wrapper(context, |context| {
125 context.buffer.lines([
126 format_args!("-webkit-animation: {value};"),
127 format_args!("animation: {value};"),
128 ]);
129 }),
130 }
131 }
132}