-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosc.css
107 lines (85 loc) · 5.25 KB
/
osc.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/** ; v0.5.6 ; LICENSE: MIT Copyright (c) 2025 Nils Riedemann
___ ____ ___ ___ ____ ____
/ __`\ /',__\ /'___\ /'___\ /',__\ /',__\
/\ \L\ \/\__, `\/\ \__/ __/\ \__//\__, `\/\__, `\
\ \____/\/\____/\ \____\/\_\ \____\/\____/\/\____/
\/___/ \/___/ \/____/\/_/\/____/\/___/ \/___/
CSS properties to animate numeric values where they are needed
using oscillators and envelopes.
https://osc.style/
*/
:where(*) {
--_osc-time-unit: 1s;
--_osc-state: var(--osc-state, running);
--_osc-env-iterations: var(--osc-env-iterations, infinite);
--_osc-global-frequency: var(--osc-frequency, 1);
--_osc-sin-frequency: var(--osc-sin-frequency, var(--_osc-global-frequency));
--_osc-cos-frequency: var(--osc-cos-frequency, var(--_osc-global-frequency));
--_osc-tri-frequency: var(--osc-tri-frequency, var(--_osc-global-frequency));
--_osc-saw-frequency: var(--osc-saw-frequency, var(--_osc-global-frequency));
--_osc-global-phase: var(--osc-phase, 0s);
--_osc-sin-phase: calc(var(--_osc-global-phase) + var(--osc-sin-phase, 0s));
--_osc-cos-phase: calc(var(--_osc-global-phase) + var(--osc-cos-phase, 0s));
--_osc-saw-phase: calc(var(--_osc-global-phase) + var(--osc-saw-phase, 0s));
--_osc-tri-phase: calc(var(--_osc-global-phase) + var(--osc-tri-phase, 0s));
/* TODO: feat: add iteration-delay (post envelope delay, poc: https://codepen.io/nocksock/pen/rNEPMjJ) */
--_osc-env-delay: var(--env-delay, 0);
--_osc-env-attack: var(--env-attack, 0);
--_osc-env-hold: var(--env-hold, 0);
--_osc-env-decay: var(--env-decay, 1);
--_osc-env-total: calc(var(--_osc-env-delay) + var(--_osc-env-attack) + var(--_osc-env-hold) + var(--_osc-env-decay));
--_osc-delay-start: calc(var(--_osc-env-delay) / var(--_osc-env-total) * 100%);
--_osc-attack-start: calc((var(--_osc-env-delay) + var(--_osc-env-attack)) / var(--_osc-env-total) * 100%);
--_osc-hold-start: calc((var(--_osc-env-attack) + var(--_osc-env-hold)) / var(--_osc-env-total) * 100%);
--_osc-decay-start: calc(var(--_osc-hold-start));
--env-dahd: linear(0 0%,
0 var(--_osc-delay-start),
1 var(--_osc-attack-start),
1 var(--_osc-hold-start),
1 var(--_osc-decay-start),
0);
--_osc-envelope: var(--env, var(--env-dahd));
/* TODO: add pulse wave (maybe w/ slope parameter?) */
--osc-only-sin: calc(1s / var(--_osc-sin-frequency)) linear var(--_osc-sin-phase) infinite osc-sin var(--_osc-state);
--osc-only-cos: calc(1s / var(--_osc-cos-frequency)) linear var(--_osc-cos-phase) infinite osc-cos var(--_osc-state);
--osc-only-saw: calc(1s / var(--_osc-saw-frequency)) linear var(--_osc-saw-phase) infinite osc-saw var(--_osc-state);
--osc-only-tri: calc(1s / var(--_osc-tri-frequency)) linear var(--_osc-tri-phase) alternate infinite osc-tri var(--_osc-state);
--osc-only-envelope: calc(var(--_osc-env-total) * var(--_osc-time-unit)) var(--_osc-envelope) var(--_osc-global-phase) forwards var(--_osc-env-iterations) env-amp var(--_osc-state);
--osc:
var(--osc-only-envelope),
var(--osc-only-sin),
var(--osc-only-cos),
var(--osc-only-saw),
var(--osc-only-tri);
/* TODO: compare performance and behaviour of ease-in-out vs calculation */
--osc-sin: calc(sin(var(--osc-_sin) * pi));
--osc-cos: calc(cos(var(--osc-_cos) * pi));
/* - normalised oscillators - */
--osc-SIN: calc((1 + var(--osc-sin)) / 2);
--osc-COS: calc((1 + var(--osc-cos)) / 2);
--osc-SAW: calc((1 + var(--osc-saw)) / 2);
--osc-TRI: calc((1 + var(--osc-tri)) / 2);
}
/* - wave forms - */
/* TODO: reconsider implications of inherits true vs false */
@property --osc-_sin { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --osc-_cos { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --osc-tri { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --osc-saw { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@keyframes osc-sin { from { --osc-_sin: -1; } to { --osc-_sin: 1; } }
@keyframes osc-cos { from { --osc-_cos: -1; } to { --osc-_cos: 1; } }
@keyframes osc-tri { from { --osc-tri: -1; } to { --osc-tri: 1; } }
@keyframes osc-saw { from { --osc-saw: -1; } to { --osc-saw: 1; } }
/* - amp envelope - */
@property --env-amp { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@keyframes env-amp { from { --env-amp: 0; } to { --env-amp: 1; } }
@property --_osc-env-total { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-env-delay { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-env-attack { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-env-hold { syntax: "<number>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-env-decay { syntax: "<number>" ; initial-value: 1 ; inherits: false ; }
@property --_osc-delay-start { syntax: "<percent>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-attack-start { syntax: "<percent>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-hold-start { syntax: "<percent>" ; initial-value: 0 ; inherits: false ; }
@property --_osc-decay-start { syntax: "<percent>" ; initial-value: 0 ; inherits: false ; }
/* TODO: declare any missing properties (also makes debugging easier) */