@twick/visualizer 0.0.1 → 0.14.2
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/.eslintrc.json +20 -20
- package/README.md +12 -12
- package/package.json +34 -31
- package/package.json.bak +34 -0
- package/src/animations/blur.tsx +60 -0
- package/src/animations/breathe.tsx +60 -0
- package/src/animations/fade.tsx +60 -0
- package/src/animations/photo-rise.tsx +66 -0
- package/src/animations/photo-zoom.tsx +73 -0
- package/src/animations/rise.tsx +118 -0
- package/src/animations/succession.tsx +77 -0
- package/src/components/frame-effects.tsx +188 -190
- package/src/components/track.tsx +237 -0
- package/src/controllers/animation.controller.ts +39 -0
- package/src/controllers/element.controller.ts +43 -0
- package/src/controllers/frame-effect.controller.tsx +30 -0
- package/src/controllers/text-effect.controller.ts +33 -0
- package/src/elements/audio.element.tsx +17 -0
- package/src/elements/caption.element.tsx +87 -0
- package/src/elements/circle.element.tsx +20 -0
- package/src/elements/icon.element.tsx +20 -0
- package/src/elements/image.element.tsx +53 -0
- package/src/elements/rect.element.tsx +22 -0
- package/src/elements/scene.element.tsx +29 -0
- package/src/elements/text.element.tsx +28 -0
- package/src/elements/video.element.tsx +55 -0
- package/src/frame-effects/circle.frame.tsx +103 -0
- package/src/frame-effects/rect.frame.tsx +103 -0
- package/src/global.css +11 -11
- package/src/helpers/caption.utils.ts +30 -40
- package/src/helpers/constants.ts +162 -158
- package/src/helpers/element.utils.ts +239 -85
- package/src/helpers/event.utils.ts +6 -0
- package/src/helpers/filters.ts +127 -127
- package/src/helpers/log.utils.ts +29 -32
- package/src/helpers/timing.utils.ts +110 -129
- package/src/helpers/types.ts +242 -146
- package/src/helpers/utils.ts +20 -0
- package/src/index.ts +6 -4
- package/src/live.tsx +16 -16
- package/src/project.ts +6 -6
- package/src/sample.ts +247 -449
- package/src/text-effects/elastic.tsx +39 -0
- package/src/text-effects/erase.tsx +58 -0
- package/src/text-effects/stream-word.tsx +60 -0
- package/src/text-effects/typewriter.tsx +59 -0
- package/src/visualizer.tsx +98 -78
- package/tsconfig.json +11 -10
- package/typedoc.json +14 -14
- package/vite.config.ts +15 -15
- package/src/components/animation.tsx +0 -7
- package/src/components/element.tsx +0 -344
- package/src/components/timeline.tsx +0 -225
package/.eslintrc.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"root": true,
|
|
3
|
-
"extends": [
|
|
4
|
-
"eslint:recommended",
|
|
5
|
-
"plugin:@typescript-eslint/recommended"
|
|
6
|
-
],
|
|
7
|
-
"parser": "@typescript-eslint/parser",
|
|
8
|
-
"plugins": ["@typescript-eslint"],
|
|
9
|
-
"parserOptions": {
|
|
10
|
-
"ecmaVersion": "latest",
|
|
11
|
-
"sourceType": "module"
|
|
12
|
-
},
|
|
13
|
-
"env": {
|
|
14
|
-
"es2022": true,
|
|
15
|
-
"node": true
|
|
16
|
-
},
|
|
17
|
-
"rules": {
|
|
18
|
-
"@typescript-eslint/no-explicit-any": "warn",
|
|
19
|
-
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
|
|
20
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"root": true,
|
|
3
|
+
"extends": [
|
|
4
|
+
"eslint:recommended",
|
|
5
|
+
"plugin:@typescript-eslint/recommended"
|
|
6
|
+
],
|
|
7
|
+
"parser": "@typescript-eslint/parser",
|
|
8
|
+
"plugins": ["@typescript-eslint"],
|
|
9
|
+
"parserOptions": {
|
|
10
|
+
"ecmaVersion": "latest",
|
|
11
|
+
"sourceType": "module"
|
|
12
|
+
},
|
|
13
|
+
"env": {
|
|
14
|
+
"es2022": true,
|
|
15
|
+
"node": true
|
|
16
|
+
},
|
|
17
|
+
"rules": {
|
|
18
|
+
"@typescript-eslint/no-explicit-any": "warn",
|
|
19
|
+
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
|
|
20
|
+
}
|
|
21
21
|
}
|
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# @twick/visualizer
|
|
2
|
-
|
|
3
|
-
A visualization library built on top of [@
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
```
|
|
7
|
-
pnpm install
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## Build
|
|
11
|
-
```
|
|
12
|
-
pnpm build
|
|
1
|
+
# @twick/visualizer
|
|
2
|
+
|
|
3
|
+
A visualization library built on top of [@twick/2d](https://github.com/re-video/2d) for creating interactive visualizations.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
```
|
|
7
|
+
pnpm install
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
```
|
|
12
|
+
pnpm build
|
|
13
13
|
```
|
package/package.json
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@twick/visualizer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"license": "Apache-2.0",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"start": "
|
|
7
|
-
"build": "tsc && vite build",
|
|
8
|
-
"docs": "typedoc --out docs src/index.ts",
|
|
9
|
-
"clean": "rimraf .turbo node_modules dist"
|
|
10
|
-
},
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"@
|
|
16
|
-
"@
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"@
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@twick/visualizer",
|
|
3
|
+
"version": "0.14.2",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "twick editor --projectFile ./src/live.tsx",
|
|
7
|
+
"build": "tsc && vite build",
|
|
8
|
+
"docs": "typedoc --out docs src/index.ts",
|
|
9
|
+
"clean": "rimraf .turbo node_modules dist"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@preact/signals": "^1.2.1",
|
|
16
|
+
"@twick/2d": "0.14.2",
|
|
17
|
+
"@twick/core": "0.14.2",
|
|
18
|
+
"@twick/renderer": "0.14.2",
|
|
19
|
+
"@twick/vite-plugin": "0.14.2",
|
|
20
|
+
"date-fns": "^4.1.0",
|
|
21
|
+
"preact": "^10.19.2",
|
|
22
|
+
"crelt": "^1.0.6",
|
|
23
|
+
"@twick/media-utils": "0.14.2"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@twick/cli": "0.14.0",
|
|
27
|
+
"@twick/ui": "0.14.0",
|
|
28
|
+
"typescript": "5.4.2",
|
|
29
|
+
"typedoc": "^0.25.8",
|
|
30
|
+
"typedoc-plugin-markdown": "^3.17.1",
|
|
31
|
+
"vite-plugin-dts": "^3.7.3",
|
|
32
|
+
"vite": "^5.1.4"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/package.json.bak
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@twick/visualizer",
|
|
3
|
+
"version": "0.14.2",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"start": "twick editor --projectFile ./src/live.tsx",
|
|
7
|
+
"build": "tsc && vite build",
|
|
8
|
+
"docs": "typedoc --out docs src/index.ts",
|
|
9
|
+
"clean": "rimraf .turbo node_modules dist"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@preact/signals": "^1.2.1",
|
|
16
|
+
"@twick/2d": "0.14.2",
|
|
17
|
+
"@twick/core": "0.14.2",
|
|
18
|
+
"@twick/renderer": "0.14.2",
|
|
19
|
+
"@twick/vite-plugin": "0.14.2",
|
|
20
|
+
"date-fns": "^4.1.0",
|
|
21
|
+
"preact": "^10.19.2",
|
|
22
|
+
"crelt": "^1.0.6",
|
|
23
|
+
"@twick/media-utils": "0.14.2"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@twick/cli": "0.14.0",
|
|
27
|
+
"@twick/ui": "0.14.0",
|
|
28
|
+
"typescript": "5.4.2",
|
|
29
|
+
"typedoc": "^0.25.8",
|
|
30
|
+
"typedoc-plugin-markdown": "^3.17.1",
|
|
31
|
+
"vite-plugin-dts": "^3.7.3",
|
|
32
|
+
"vite": "^5.1.4"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { waitFor } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* BlurAnimation applies a blur effect to an element or its container
|
|
6
|
+
* during enter, exit, or both animations.
|
|
7
|
+
*
|
|
8
|
+
* Available animation modes:
|
|
9
|
+
* - "enter": Starts blurred and gradually becomes clear.
|
|
10
|
+
* - "exit": Starts clear and gradually becomes blurred.
|
|
11
|
+
* - "both": Blurs in, clears, then blurs out.
|
|
12
|
+
*
|
|
13
|
+
* @param elementRef - Reference to the main element.
|
|
14
|
+
* @param containerRef - Optional reference to a container element.
|
|
15
|
+
* @param interval - Duration (in frames or ms) of each blur transition.
|
|
16
|
+
* @param duration - Total duration of the animation.
|
|
17
|
+
* @param intensity - Maximum blur strength (default: 25).
|
|
18
|
+
* @param animate - Animation phase ("enter" | "exit" | "both").
|
|
19
|
+
*/
|
|
20
|
+
export const BlurAnimation = {
|
|
21
|
+
name: "blur",
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generator function controlling the blur animation.
|
|
25
|
+
*/
|
|
26
|
+
*run({
|
|
27
|
+
elementRef,
|
|
28
|
+
containerRef,
|
|
29
|
+
interval,
|
|
30
|
+
duration,
|
|
31
|
+
intensity = 25,
|
|
32
|
+
animate,
|
|
33
|
+
}: AnimationParams) {
|
|
34
|
+
// Choose containerRef if provided; otherwise, fallback to elementRef
|
|
35
|
+
const ref = containerRef ?? elementRef;
|
|
36
|
+
|
|
37
|
+
let animationInterval = Math.min(interval, duration);
|
|
38
|
+
if (animate === "enter") {
|
|
39
|
+
// Start fully blurred
|
|
40
|
+
ref().filters.blur(intensity);
|
|
41
|
+
// Animate to no blur over 'interval'
|
|
42
|
+
yield* ref().filters.blur(0, animationInterval);
|
|
43
|
+
} else if (animate === "exit") {
|
|
44
|
+
// Wait for the time before exit animation starts
|
|
45
|
+
yield* waitFor(duration - animationInterval);
|
|
46
|
+
// Animate from no blur to full blur over 'interval'
|
|
47
|
+
yield* ref().filters.blur(intensity, animationInterval);
|
|
48
|
+
} else if (animate === "both") {
|
|
49
|
+
animationInterval = Math.min(interval, duration/2);
|
|
50
|
+
// Start fully blurred
|
|
51
|
+
ref().filters.blur(intensity);
|
|
52
|
+
// Animate to no blur
|
|
53
|
+
yield* ref().filters.blur(0, animationInterval);
|
|
54
|
+
// Wait until exit animation
|
|
55
|
+
yield* waitFor(duration - animationInterval);
|
|
56
|
+
// Animate to full blur again
|
|
57
|
+
yield* ref().filters.blur(intensity, animationInterval);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Vector2 } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
import { getTimingFunction } from "../helpers/timing.utils";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* BreatheAnimation applies a smooth scale in/out effect to simulate
|
|
7
|
+
* a "breathing" motion.
|
|
8
|
+
*
|
|
9
|
+
* Available modes:
|
|
10
|
+
* - "in": Gradually scales down (shrinks) to the target intensity.
|
|
11
|
+
* - "out": Starts scaled down, then grows back to original size.
|
|
12
|
+
*
|
|
13
|
+
* @param elementRef - Reference to the main element to animate.
|
|
14
|
+
* @param containerRef - Optional reference to a container element.
|
|
15
|
+
* @param mode - Animation phase ("in" | "out").
|
|
16
|
+
* @param duration - Duration of the scaling animation.
|
|
17
|
+
* @param intensity - Target scale factor (default: 0.5).
|
|
18
|
+
*/
|
|
19
|
+
export const BreatheAnimation = {
|
|
20
|
+
name: "breathe",
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generator function controlling the breathing scale animation.
|
|
24
|
+
*/
|
|
25
|
+
*run({
|
|
26
|
+
elementRef,
|
|
27
|
+
containerRef,
|
|
28
|
+
mode,
|
|
29
|
+
duration,
|
|
30
|
+
intensity = 0.5,
|
|
31
|
+
}: AnimationParams) {
|
|
32
|
+
// Use containerRef if provided, otherwise fallback to elementRef
|
|
33
|
+
const ref = containerRef ?? elementRef;
|
|
34
|
+
|
|
35
|
+
// Get the current scale of the element
|
|
36
|
+
const scale = ref().scale();
|
|
37
|
+
|
|
38
|
+
if (mode === "in") {
|
|
39
|
+
// Animate scaling down to (original scale * intensity)
|
|
40
|
+
yield* ref().scale(
|
|
41
|
+
new Vector2(scale.x * intensity, scale.y * intensity),
|
|
42
|
+
duration,
|
|
43
|
+
getTimingFunction("easeInSine")
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (mode === "out") {
|
|
48
|
+
// Immediately set to scaled down size
|
|
49
|
+
ref().scale(
|
|
50
|
+
new Vector2(scale.x * intensity, scale.y * intensity)
|
|
51
|
+
);
|
|
52
|
+
// Animate scaling back up to original size
|
|
53
|
+
yield* ref().scale(
|
|
54
|
+
new Vector2(scale.x, scale.y),
|
|
55
|
+
duration,
|
|
56
|
+
getTimingFunction("easeOutSine")
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { waitFor } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* FadeAnimation applies a simple fade-in and fade-out effect
|
|
6
|
+
* by adjusting opacity.
|
|
7
|
+
*
|
|
8
|
+
* Available animation modes:
|
|
9
|
+
* - "enter": Starts transparent and fades in to fully opaque.
|
|
10
|
+
* - "exit": Waits, then fades out to transparent.
|
|
11
|
+
* - "both": Fades in, waits, then fades out.
|
|
12
|
+
*
|
|
13
|
+
* @param elementRef - Reference to the main element to animate.
|
|
14
|
+
* @param containerRef - Optional reference to a container element.
|
|
15
|
+
* @param interval - Duration of the fade transition (in frames or ms).
|
|
16
|
+
* @param duration - Total duration of the animation.
|
|
17
|
+
* @param animate - Animation phase ("enter" | "exit" | "both").
|
|
18
|
+
*/
|
|
19
|
+
export const FadeAnimation = {
|
|
20
|
+
name: "fade",
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generator function controlling the fade animation.
|
|
24
|
+
*/
|
|
25
|
+
*run({
|
|
26
|
+
elementRef,
|
|
27
|
+
containerRef,
|
|
28
|
+
interval,
|
|
29
|
+
duration,
|
|
30
|
+
animate,
|
|
31
|
+
}: AnimationParams) {
|
|
32
|
+
// Use containerRef if provided, otherwise fallback to elementRef
|
|
33
|
+
const ref = containerRef ?? elementRef;
|
|
34
|
+
|
|
35
|
+
let animationInterval = Math.min(interval, duration);
|
|
36
|
+
if (animate === "enter") {
|
|
37
|
+
// Start fully transparent
|
|
38
|
+
ref().opacity(0);
|
|
39
|
+
// Fade in to full opacity over 'interval'
|
|
40
|
+
yield* ref().opacity(1, animationInterval);
|
|
41
|
+
|
|
42
|
+
} else if (animate === "exit") {
|
|
43
|
+
// Wait until it's time to start fading out
|
|
44
|
+
yield* waitFor(duration - animationInterval);
|
|
45
|
+
// Fade out to transparent over 'interval'
|
|
46
|
+
yield* ref().opacity(0, animationInterval);
|
|
47
|
+
|
|
48
|
+
} else if (animate === "both") {
|
|
49
|
+
animationInterval = Math.min(interval, duration/2);
|
|
50
|
+
// Start fully transparent
|
|
51
|
+
ref().opacity(0);
|
|
52
|
+
// Fade in to full opacity
|
|
53
|
+
yield* ref().opacity(1, animationInterval);
|
|
54
|
+
// Wait for the remaining duration before fade-out
|
|
55
|
+
yield* waitFor(duration - animationInterval);
|
|
56
|
+
// Fade out to transparent
|
|
57
|
+
yield* ref().opacity(0, animationInterval);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AnimationParams } from "../helpers/types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PhotoRiseAnimation applies a smooth directional movement to a photo element.
|
|
5
|
+
*
|
|
6
|
+
* Behavior:
|
|
7
|
+
* - Starts offset in a given direction (up, down, left, or right).
|
|
8
|
+
* - Animates back to the original position over the specified duration.
|
|
9
|
+
*
|
|
10
|
+
* Available directions:
|
|
11
|
+
* - "up": Starts below and moves upward.
|
|
12
|
+
* - "down": Starts above and moves downward.
|
|
13
|
+
* - "left": Starts to the right and moves leftward.
|
|
14
|
+
* - "right": Starts to the left and moves rightward.
|
|
15
|
+
*
|
|
16
|
+
* @param elementRef - Reference to the photo element to animate.
|
|
17
|
+
* @param containerRef - Optional reference to a container element (required for this animation).
|
|
18
|
+
* @param direction - Direction of the movement ("up" | "down" | "left" | "right").
|
|
19
|
+
* @param duration - Duration of the movement animation.
|
|
20
|
+
* @param intensity - Offset distance in pixels (default: 200).
|
|
21
|
+
*/
|
|
22
|
+
export const PhotoRiseAnimation = {
|
|
23
|
+
name: "photo-rise",
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generator function controlling the photo rise animation.
|
|
27
|
+
*/
|
|
28
|
+
*run({
|
|
29
|
+
elementRef,
|
|
30
|
+
containerRef,
|
|
31
|
+
direction,
|
|
32
|
+
duration,
|
|
33
|
+
intensity = 200,
|
|
34
|
+
}: AnimationParams) {
|
|
35
|
+
// Only run if a containerRef is provided
|
|
36
|
+
if (containerRef) {
|
|
37
|
+
// Get the element's current position
|
|
38
|
+
const pos = elementRef().position();
|
|
39
|
+
|
|
40
|
+
if (direction === "up") {
|
|
41
|
+
// Start offset below
|
|
42
|
+
elementRef().y(pos.y + intensity);
|
|
43
|
+
// Animate moving upward to the original position
|
|
44
|
+
yield* elementRef().y(pos.y, duration);
|
|
45
|
+
|
|
46
|
+
} else if (direction === "down") {
|
|
47
|
+
// Start offset above
|
|
48
|
+
elementRef().y(pos.y - intensity);
|
|
49
|
+
// Animate moving downward to the original position
|
|
50
|
+
yield* elementRef().y(pos.y, duration);
|
|
51
|
+
|
|
52
|
+
} else if (direction === "left") {
|
|
53
|
+
// Start offset to the right
|
|
54
|
+
elementRef().x(pos.x + intensity);
|
|
55
|
+
// Animate moving left to the original position
|
|
56
|
+
yield* elementRef().x(pos.x, duration);
|
|
57
|
+
|
|
58
|
+
} else if (direction === "right") {
|
|
59
|
+
// Start offset to the left
|
|
60
|
+
elementRef().x(pos.x - intensity);
|
|
61
|
+
// Animate moving right to the original position
|
|
62
|
+
yield* elementRef().x(pos.x, duration);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { Vector2 } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* PhotoZoomAnimation applies a smooth zoom-in or zoom-out effect
|
|
6
|
+
* on a photo element.
|
|
7
|
+
*
|
|
8
|
+
* Available animation modes:
|
|
9
|
+
* - "in": Starts zoomed in and smoothly scales back to the original size.
|
|
10
|
+
* - "out": Starts at normal size and smoothly scales up to the target zoom level.
|
|
11
|
+
*
|
|
12
|
+
* @param elementRef - Reference to the photo element to animate.
|
|
13
|
+
* @param containerRef - Optional reference to a container element (required for this animation).
|
|
14
|
+
* @param mode - Animation phase ("in" | "out").
|
|
15
|
+
* @param duration - Duration of the zoom animation.
|
|
16
|
+
* @param intensity - Zoom scale multiplier (default: 1.5).
|
|
17
|
+
*/
|
|
18
|
+
export const PhotoZoomAnimation = {
|
|
19
|
+
name: "photo-zoom",
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Generator function controlling the photo zoom animation.
|
|
23
|
+
*/
|
|
24
|
+
*run({
|
|
25
|
+
elementRef,
|
|
26
|
+
containerRef,
|
|
27
|
+
mode,
|
|
28
|
+
duration,
|
|
29
|
+
intensity = 1.5,
|
|
30
|
+
}: AnimationParams) {
|
|
31
|
+
// Only run if a containerRef is provided
|
|
32
|
+
if (containerRef) {
|
|
33
|
+
// Get the element's current scale
|
|
34
|
+
const elementScale = elementRef().scale();
|
|
35
|
+
|
|
36
|
+
if (mode === "in") {
|
|
37
|
+
// Instantly set to zoomed-in scale
|
|
38
|
+
yield elementRef().scale(
|
|
39
|
+
new Vector2(
|
|
40
|
+
elementScale.x * intensity,
|
|
41
|
+
elementScale.y * intensity
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
// Smoothly scale back to original size over 'duration'
|
|
45
|
+
yield* elementRef().scale(
|
|
46
|
+
new Vector2(
|
|
47
|
+
elementScale.x,
|
|
48
|
+
elementScale.y
|
|
49
|
+
),
|
|
50
|
+
duration
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (mode === "out") {
|
|
55
|
+
// Start at original scale
|
|
56
|
+
elementRef().scale(
|
|
57
|
+
new Vector2(
|
|
58
|
+
elementScale.x,
|
|
59
|
+
elementScale.y
|
|
60
|
+
)
|
|
61
|
+
);
|
|
62
|
+
// Smoothly scale up to zoomed-in scale over 'duration'
|
|
63
|
+
yield* elementRef().scale(
|
|
64
|
+
new Vector2(
|
|
65
|
+
elementScale.x * intensity,
|
|
66
|
+
elementScale.y * intensity
|
|
67
|
+
),
|
|
68
|
+
duration
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { all, waitFor, delay } from "@twick/core";
|
|
2
|
+
import { AnimationParams } from "../helpers/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* RiseAnimation combines vertical motion and opacity transitions
|
|
6
|
+
* to create a "rising" (or "falling") appearance/disappearance effect.
|
|
7
|
+
*
|
|
8
|
+
* Available animation modes:
|
|
9
|
+
* - "enter": Starts offset and transparent, moves into position while fading in.
|
|
10
|
+
* - "exit": Waits, then moves out of position while fading out.
|
|
11
|
+
* - "both": Enters, waits, and exits in a continuous sequence.
|
|
12
|
+
*
|
|
13
|
+
* @param elementRef - Reference to the main element to animate.
|
|
14
|
+
* @param containerRef - Optional reference to a container element.
|
|
15
|
+
* @param interval - Duration of movement and opacity transitions (default: 0.25).
|
|
16
|
+
* @param duration - Total duration of the animation.
|
|
17
|
+
* @param animate - Animation phase ("enter" | "exit" | "both").
|
|
18
|
+
* @param direction - Direction to animate ("up" or "down").
|
|
19
|
+
* @param intensity - Number of units to offset position vertically (default: 200).
|
|
20
|
+
*/
|
|
21
|
+
export const RiseAnimation = {
|
|
22
|
+
name: "rise",
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Generator function controlling the rise/fall animation.
|
|
26
|
+
*/
|
|
27
|
+
*run({
|
|
28
|
+
elementRef,
|
|
29
|
+
containerRef,
|
|
30
|
+
interval = 0.25,
|
|
31
|
+
duration,
|
|
32
|
+
animate,
|
|
33
|
+
direction,
|
|
34
|
+
intensity = 200,
|
|
35
|
+
}: AnimationParams) {
|
|
36
|
+
// Use containerRef if provided, otherwise fallback to elementRef
|
|
37
|
+
const ref = containerRef ?? elementRef;
|
|
38
|
+
|
|
39
|
+
// Get the element's current position
|
|
40
|
+
const pos = ref().position();
|
|
41
|
+
|
|
42
|
+
let animationInterval = Math.min(interval, duration);
|
|
43
|
+
|
|
44
|
+
if (animate === "enter") {
|
|
45
|
+
// Start fully transparent
|
|
46
|
+
ref().opacity(0);
|
|
47
|
+
|
|
48
|
+
if (direction === "up") {
|
|
49
|
+
// Offset element below final position
|
|
50
|
+
ref().y(pos.y + intensity);
|
|
51
|
+
// Animate moving up while fading in
|
|
52
|
+
yield* all(
|
|
53
|
+
ref().opacity(1, animationInterval / 4),
|
|
54
|
+
ref().y(pos.y, animationInterval)
|
|
55
|
+
);
|
|
56
|
+
} else if (direction === "down") {
|
|
57
|
+
// Offset element above final position
|
|
58
|
+
ref().y(pos.y - intensity);
|
|
59
|
+
// Animate moving down while fading in
|
|
60
|
+
yield* all(
|
|
61
|
+
ref().opacity(1, animationInterval / 4),
|
|
62
|
+
ref().y(pos.y, animationInterval)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
} else if (animate === "exit") {
|
|
66
|
+
// Wait until exit animation starts
|
|
67
|
+
yield* waitFor(duration - animationInterval);
|
|
68
|
+
|
|
69
|
+
if (direction === "up") {
|
|
70
|
+
// Animate moving up while fading out (opacity fades slightly after motion starts)
|
|
71
|
+
yield* all(
|
|
72
|
+
delay((3 * animationInterval) / 4, ref().opacity(0, animationInterval / 4)),
|
|
73
|
+
ref().y(pos.y - intensity, animationInterval)
|
|
74
|
+
);
|
|
75
|
+
} else if (direction === "down") {
|
|
76
|
+
// Animate moving down while fading out
|
|
77
|
+
yield* all(
|
|
78
|
+
delay((3 * animationInterval) / 4, ref().opacity(0, animationInterval / 4)),
|
|
79
|
+
ref().y(pos.y + intensity, animationInterval)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
} else if (animate === "both") {
|
|
83
|
+
animationInterval = Math.min(interval, duration/2);
|
|
84
|
+
// Start fully transparent
|
|
85
|
+
ref().opacity(0);
|
|
86
|
+
|
|
87
|
+
if (direction === "up") {
|
|
88
|
+
// Enter animation: move up while fading in
|
|
89
|
+
ref().y(pos.y + intensity);
|
|
90
|
+
yield* all(
|
|
91
|
+
ref().opacity(1, animationInterval / 4),
|
|
92
|
+
ref().y(pos.y, animationInterval)
|
|
93
|
+
);
|
|
94
|
+
// Wait for the remaining duration
|
|
95
|
+
yield* waitFor(duration - animationInterval);
|
|
96
|
+
// Exit animation: move up further while fading out
|
|
97
|
+
yield* all(
|
|
98
|
+
delay((3 * animationInterval) / 4, ref().opacity(0, animationInterval / 4)),
|
|
99
|
+
ref().y(pos.y - intensity, animationInterval)
|
|
100
|
+
);
|
|
101
|
+
} else if (direction === "down") {
|
|
102
|
+
// Enter animation: move down while fading in
|
|
103
|
+
ref().y(pos.y - intensity);
|
|
104
|
+
yield* all(
|
|
105
|
+
ref().opacity(1, animationInterval / 4),
|
|
106
|
+
ref().y(pos.y, animationInterval)
|
|
107
|
+
);
|
|
108
|
+
// Wait for the remaining duration
|
|
109
|
+
yield* waitFor(duration - animationInterval);
|
|
110
|
+
// Exit animation: move down further while fading out
|
|
111
|
+
yield* all(
|
|
112
|
+
delay((3 * animationInterval) / 4, ref().opacity(0, animationInterval / 4)),
|
|
113
|
+
ref().y(pos.y + intensity, animationInterval)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|