@maxigarcia/theme-transitions 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -6
- package/dist/circular-reveal/index.js +3 -3
- package/dist/fall/index.css +57 -0
- package/dist/fall/index.d.ts +6 -0
- package/dist/fall/index.d.ts.map +1 -0
- package/dist/fall/index.js +17 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/page-turn/index.css +110 -0
- package/dist/page-turn/index.d.ts +9 -0
- package/dist/page-turn/index.d.ts.map +1 -0
- package/dist/page-turn/index.js +18 -0
- package/dist/sweep-reveal/index.js +3 -3
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +0 -5
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @maxigarcia/theme-transitions
|
|
2
2
|
|
|
3
|
-
Lightweight, CSS-first theme transitions for the web. Wrap your theme change in the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) and reveal the new theme with a **circular** or **
|
|
3
|
+
Lightweight, CSS-first theme transitions for the web. Wrap your theme change in the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) and reveal the new theme with a **circular**, **sweep**, **fall**, or **page turn** animation—no animation framework required.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -14,16 +14,20 @@ npm install @maxigarcia/theme-transitions
|
|
|
14
14
|
| --------------- | ---------------------------------------------------------------- |
|
|
15
15
|
| Circular reveal | [src/circular-reveal/README.md](./src/circular-reveal/README.md) |
|
|
16
16
|
| Sweep reveal | [src/sweep-reveal/README.md](./src/sweep-reveal/README.md) |
|
|
17
|
+
| Fall | [src/fall/README.md](./src/fall/README.md) |
|
|
18
|
+
| Page turn | [src/page-turn/README.md](./src/page-turn/README.md) |
|
|
17
19
|
|
|
18
20
|
Each module has its own README with setup, API, and usage examples.
|
|
19
21
|
|
|
20
22
|
## Package exports
|
|
21
23
|
|
|
22
|
-
| Import | Purpose
|
|
23
|
-
| --------------------------------------------------- |
|
|
24
|
-
| `@maxigarcia/theme-transitions` | `onCircularRevealAnimation`, `onSweepRevealAnimation`, types |
|
|
25
|
-
| `@maxigarcia/theme-transitions/
|
|
26
|
-
| `@maxigarcia/theme-transitions/
|
|
24
|
+
| Import | Purpose |
|
|
25
|
+
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
26
|
+
| `@maxigarcia/theme-transitions` | `onCircularRevealAnimation`, `onSweepRevealAnimation`, `onFallAnimation`, `onPageTurnAnimation`, types |
|
|
27
|
+
| `@maxigarcia/theme-transitions/page-turn.css` | Styles for page turn |
|
|
28
|
+
| `@maxigarcia/theme-transitions/circular-reveal.css` | Styles for circular reveal |
|
|
29
|
+
| `@maxigarcia/theme-transitions/fall.css` | Styles for fall |
|
|
30
|
+
| `@maxigarcia/theme-transitions/sweep-reveal.css` | Styles for sweep reveal |
|
|
27
31
|
|
|
28
32
|
## Live demo
|
|
29
33
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $html
|
|
1
|
+
import { $html } from '../utils/index.js';
|
|
2
2
|
export function onCircularRevealAnimation(apply, origin, options) {
|
|
3
3
|
if (!document.startViewTransition) {
|
|
4
4
|
apply();
|
|
@@ -16,12 +16,12 @@ export function onCircularRevealAnimation(apply, origin, options) {
|
|
|
16
16
|
}
|
|
17
17
|
html.style.setProperty('--theme-reveal-x', `${x}%`);
|
|
18
18
|
html.style.setProperty('--theme-reveal-y', `${y}%`);
|
|
19
|
-
document.startViewTransition(apply);
|
|
19
|
+
const transition = document.startViewTransition(apply);
|
|
20
20
|
const animationComplete = () => {
|
|
21
21
|
html.style.removeProperty('--theme-reveal-x');
|
|
22
22
|
html.style.removeProperty('--theme-reveal-y');
|
|
23
23
|
html.style.removeProperty('--theme-reveal-blur');
|
|
24
24
|
html.classList.remove('circular-reveal', 'circular-reveal--blur-circle');
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
void transition.finished.finally(animationComplete);
|
|
27
27
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@keyframes theme-fall-out {
|
|
2
|
+
0% {
|
|
3
|
+
transform: translateY(0) scaleY(1) scaleX(1) skewY(0deg);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
15% {
|
|
7
|
+
transform: translateY(3vh) scaleY(0.94) scaleX(1.02) skewY(1deg);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
100% {
|
|
11
|
+
transform: translateY(105%) scaleY(0.75) scaleX(1.06) skewY(4deg);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
html.fall::view-transition-old(root),
|
|
16
|
+
html.fall::view-transition-new(root),
|
|
17
|
+
html.fall::view-transition-old(*),
|
|
18
|
+
html.fall::view-transition-new(*) {
|
|
19
|
+
mix-blend-mode: normal;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
html.fall::view-transition-group(root),
|
|
23
|
+
html.fall::view-transition-group(*) {
|
|
24
|
+
animation: none;
|
|
25
|
+
transform-origin: bottom center;
|
|
26
|
+
overflow: visible;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
html.fall::view-transition-image-pair(root),
|
|
30
|
+
html.fall::view-transition-image-pair(*) {
|
|
31
|
+
isolation: isolate;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
html.fall::view-transition-old(root),
|
|
35
|
+
html.fall::view-transition-old(*) {
|
|
36
|
+
animation: theme-fall-out var(--theme-fall-duration, 700ms) cubic-bezier(0.33, 0, 0.67, 0.15) forwards;
|
|
37
|
+
transform-origin: bottom center;
|
|
38
|
+
opacity: 1;
|
|
39
|
+
z-index: 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
html.fall::view-transition-new(root),
|
|
43
|
+
html.fall::view-transition-new(*) {
|
|
44
|
+
animation: none;
|
|
45
|
+
opacity: 1;
|
|
46
|
+
z-index: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* Reduce motion */
|
|
50
|
+
@media (prefers-reduced-motion: reduce) {
|
|
51
|
+
html.fall::view-transition-old(root),
|
|
52
|
+
html.fall::view-transition-new(root),
|
|
53
|
+
html.fall::view-transition-old(*),
|
|
54
|
+
html.fall::view-transition-new(*) {
|
|
55
|
+
animation: none;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fall/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,IAAI,EACjB,OAAO,CAAC,EAAE,WAAW,GACpB,IAAI,CAqBN"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { $html } from '../utils/index.js';
|
|
2
|
+
export function onFallAnimation(apply, options) {
|
|
3
|
+
if (!document.startViewTransition) {
|
|
4
|
+
apply();
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const duration = options?.duration ?? 700;
|
|
8
|
+
const html = $html();
|
|
9
|
+
html.classList.add('fall');
|
|
10
|
+
html.style.setProperty('--theme-fall-duration', `${duration}ms`);
|
|
11
|
+
const transition = document.startViewTransition(apply);
|
|
12
|
+
const animationComplete = () => {
|
|
13
|
+
html.classList.remove('fall');
|
|
14
|
+
html.style.removeProperty('--theme-fall-duration');
|
|
15
|
+
};
|
|
16
|
+
void transition.finished.finally(animationComplete);
|
|
17
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
@keyframes theme-page-turn-out-left {
|
|
2
|
+
0% {
|
|
3
|
+
filter: brightness(1);
|
|
4
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(0deg) rotateX(0deg);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
16% {
|
|
8
|
+
filter: brightness(0.98);
|
|
9
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(-14deg) rotateX(0.5deg);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
42% {
|
|
13
|
+
filter: brightness(0.92) drop-shadow(-8px 2px 6px rgb(0 0 0 / 0.14));
|
|
14
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(-50deg) rotateX(0.25deg);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
72% {
|
|
18
|
+
filter: brightness(0.9) drop-shadow(-4px 1px 4px rgb(0 0 0 / 0.1));
|
|
19
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(-80deg) rotateX(0deg);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
100% {
|
|
23
|
+
filter: brightness(0.9);
|
|
24
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(-90deg) rotateX(0deg);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@keyframes theme-page-turn-out-right {
|
|
29
|
+
0% {
|
|
30
|
+
filter: brightness(1);
|
|
31
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(0deg) rotateX(0deg);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
16% {
|
|
35
|
+
filter: brightness(0.98);
|
|
36
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(14deg) rotateX(0.5deg);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
42% {
|
|
40
|
+
filter: brightness(0.92) drop-shadow(8px 2px 6px rgb(0 0 0 / 0.14));
|
|
41
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(50deg) rotateX(0.25deg);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
72% {
|
|
45
|
+
filter: brightness(0.9) drop-shadow(4px 1px 4px rgb(0 0 0 / 0.1));
|
|
46
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(80deg) rotateX(0deg);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
100% {
|
|
50
|
+
filter: brightness(0.9);
|
|
51
|
+
transform: perspective(var(--theme-page-turn-perspective, 2000px)) rotateY(90deg) rotateX(0deg);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
html.page-turn::view-transition-old(root),
|
|
56
|
+
html.page-turn::view-transition-new(root),
|
|
57
|
+
html.page-turn::view-transition-old(*),
|
|
58
|
+
html.page-turn::view-transition-new(*) {
|
|
59
|
+
mix-blend-mode: normal;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
html.page-turn::view-transition-group(root),
|
|
63
|
+
html.page-turn::view-transition-group(*) {
|
|
64
|
+
animation: none;
|
|
65
|
+
overflow: visible;
|
|
66
|
+
transform-style: preserve-3d;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
html.page-turn::view-transition-image-pair(root),
|
|
70
|
+
html.page-turn::view-transition-image-pair(*) {
|
|
71
|
+
isolation: isolate;
|
|
72
|
+
transform-style: preserve-3d;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
html.page-turn::view-transition-new(root),
|
|
76
|
+
html.page-turn::view-transition-new(*) {
|
|
77
|
+
animation: none;
|
|
78
|
+
opacity: 1;
|
|
79
|
+
transform: translateZ(-1px);
|
|
80
|
+
z-index: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
html.page-turn::view-transition-old(root),
|
|
84
|
+
html.page-turn::view-transition-old(*) {
|
|
85
|
+
animation: theme-page-turn-out-left var(--theme-page-turn-duration, 750ms) cubic-bezier(0.45, 0.05, 0.55, 0.95)
|
|
86
|
+
forwards;
|
|
87
|
+
backface-visibility: hidden;
|
|
88
|
+
opacity: 1;
|
|
89
|
+
transform-origin: left center;
|
|
90
|
+
transform-style: preserve-3d;
|
|
91
|
+
z-index: 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
html.page-turn--right::view-transition-old(root),
|
|
95
|
+
html.page-turn--right::view-transition-old(*) {
|
|
96
|
+
animation-name: theme-page-turn-out-right;
|
|
97
|
+
transform-origin: right center;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Reduce motion */
|
|
101
|
+
@media (prefers-reduced-motion: reduce) {
|
|
102
|
+
html.page-turn::view-transition-old(root),
|
|
103
|
+
html.page-turn::view-transition-new(root),
|
|
104
|
+
html.page-turn::view-transition-old(*),
|
|
105
|
+
html.page-turn::view-transition-new(*) {
|
|
106
|
+
animation: none;
|
|
107
|
+
filter: none;
|
|
108
|
+
transform: none;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type PageTurnEdge = 'left' | 'right';
|
|
2
|
+
export interface PageTurnOptions {
|
|
3
|
+
/** Page turn duration in milliseconds. Defaults to `750`. */
|
|
4
|
+
duration?: number;
|
|
5
|
+
/** Edge the page pivots on. Defaults to `left`. */
|
|
6
|
+
edge?: PageTurnEdge;
|
|
7
|
+
}
|
|
8
|
+
export declare function onPageTurnAnimation(apply: () => void, options?: PageTurnOptions): void;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/page-turn/index.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,IAAI,EACjB,OAAO,CAAC,EAAE,eAAe,GACxB,IAAI,CAqBN"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { $html } from '../utils/index.js';
|
|
2
|
+
export function onPageTurnAnimation(apply, options) {
|
|
3
|
+
if (!document.startViewTransition) {
|
|
4
|
+
apply();
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const duration = options?.duration ?? 750;
|
|
8
|
+
const edge = options?.edge ?? 'left';
|
|
9
|
+
const html = $html();
|
|
10
|
+
html.classList.add('page-turn', `page-turn--${edge}`);
|
|
11
|
+
html.style.setProperty('--theme-page-turn-duration', `${duration}ms`);
|
|
12
|
+
const transition = document.startViewTransition(apply);
|
|
13
|
+
const animationComplete = () => {
|
|
14
|
+
html.classList.remove('page-turn', `page-turn--${edge}`);
|
|
15
|
+
html.style.removeProperty('--theme-page-turn-duration');
|
|
16
|
+
};
|
|
17
|
+
void transition.finished.finally(animationComplete);
|
|
18
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $html
|
|
1
|
+
import { $html } from '../utils/index.js';
|
|
2
2
|
export function onSweepRevealAnimation(apply, direction = 'up') {
|
|
3
3
|
if (!document.startViewTransition) {
|
|
4
4
|
apply();
|
|
@@ -19,11 +19,11 @@ export function onSweepRevealAnimation(apply, direction = 'up') {
|
|
|
19
19
|
html.classList.add('sweep-reveal');
|
|
20
20
|
html.style.setProperty('--theme-reveal-direction-from', directionFrom);
|
|
21
21
|
html.style.setProperty('--theme-reveal-direction-to', directionTo);
|
|
22
|
-
document.startViewTransition(apply);
|
|
22
|
+
const transition = document.startViewTransition(apply);
|
|
23
23
|
const animationComplete = () => {
|
|
24
24
|
html.classList.remove('sweep-reveal');
|
|
25
25
|
html.style.removeProperty('--theme-reveal-direction-from');
|
|
26
26
|
html.style.removeProperty('--theme-reveal-direction-to');
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
void transition.finished.finally(animationComplete);
|
|
29
29
|
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,gBAEpB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,gBAEpB"}
|
package/dist/utils/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxigarcia/theme-transitions",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"homepage": "https://github.com/MaxiGarcia13/js-theme-animation-monorepo/tree/main/packages/theme-transitions#readme",
|
|
7
7
|
"repository": {
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
"types": "./dist/index.d.ts",
|
|
32
32
|
"import": "./dist/index.js"
|
|
33
33
|
},
|
|
34
|
+
"./page-turn.css": "./dist/page-turn/index.css",
|
|
34
35
|
"./circular-reveal.css": "./dist/circular-reveal/index.css",
|
|
36
|
+
"./fall.css": "./dist/fall/index.css",
|
|
35
37
|
"./sweep-reveal.css": "./dist/sweep-reveal/index.css"
|
|
36
38
|
},
|
|
37
39
|
"main": "./dist/index.js",
|