Skip to content

Commit a1a1237

Browse files
committed
chore: update gsap version to 3.14.2 in pnpm-lock and pnpm-workspace; add new gsap animation examples and enhance documentation with additional links and demos
1 parent df33626 commit a1a1237

31 files changed

+1378
-34
lines changed

docs/.vitepress/config.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const themeConfig: DefaultTheme.Config = {
3232
{ text: 'Events', link: '/examples/events/buttons' },
3333
{ text: 'Filters', link: '/examples/filters/blur' },
3434
{ text: 'Graphics', link: '/examples/graphics/basic_shapes' },
35+
{ text: 'Gsap', link: '/examples/gsap/animation_basic' },
3536
// { text: 'Text', link: '/examples/text/bitmap-text' },
3637
// { text: 'Events', link: '/examples/events/click' },
3738
// { text: 'Masks', link: '/examples/masks/filter' },
@@ -198,6 +199,20 @@ const themeConfig: DefaultTheme.Config = {
198199
{ text: 'Texture Fill', link: '/examples/graphics/texture-fill' },
199200
],
200201
},
202+
{
203+
text: 'Gsap',
204+
collapsed: true,
205+
items: [
206+
{ text: 'Animation / Basic', link: '/examples/gsap/animation_basic' },
207+
{ text: 'Animation / Confetti', link: '/examples/gsap/animation_confetti' },
208+
{ text: 'Animation / Keyframe', link: '/examples/gsap/animation_keyframe' },
209+
{ text: 'Animation / Physics / Particles', link: '/examples/gsap/animation_physics_particles' },
210+
{ text: 'Animation / Timeline', link: '/examples/gsap/animation_timeline' },
211+
{ text: 'Interaction / Inertia', link: '/examples/gsap/interaction_inertia' },
212+
{ text: 'Interaction / MoveTo', link: '/examples/gsap/interaction_moveto' },
213+
{ text: 'Physics', link: '/examples/gsap/physics' },
214+
],
215+
},
201216
// {
202217
// text: 'Container',
203218
// collapsed: true,

docs/examples/graphics/demo/svg_file.vue

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,11 @@
11
<script lang="ts" setup>
2-
import type { Graphics as GraphicsElement } from 'pixi.js'
32
import { ref } from 'vue'
43
import { onTick, useScreen } from 'vue3-pixi'
54
65
const screen = useScreen()
7-
const graphicsRef = ref<GraphicsElement>()
86
const rotation = ref(0)
97
const scale = ref(2)
108
11-
function onDraw(graphics: GraphicsElement) {
12-
if (!graphicsRef.value) {
13-
graphicsRef.value = graphics
14-
// line it up as this svg is not centered
15-
const bounds = graphics.getLocalBounds()
16-
graphics.pivot.set(
17-
(bounds.x + bounds.width) / 2,
18-
(bounds.y + bounds.height) / 2,
19-
)
20-
}
21-
}
22-
239
onTick(() => {
2410
rotation.value += 0.01
2511
scale.value = 2 + Math.sin(rotation.value)
@@ -29,22 +15,24 @@ onTick(() => {
2915
<template>
3016
<assets
3117
:entry="{
32-
alias: 'tiger',
3318
src: 'https://pixijs.com/assets/tiger.svg',
34-
data: {
35-
parseAsGraphicsContext: true,
36-
},
19+
data: { parseAsGraphicsContext: true },
3720
}"
38-
@loaded="console.log"
3921
>
4022
<template #default="{ data }">
4123
<graphics
42-
:texture="data"
24+
:context="data"
4325
:x="screen.width / 2"
4426
:y="screen.height / 2"
4527
:rotation="rotation"
4628
:scale="scale"
47-
@effect="onDraw"
29+
@effect="graphics => {
30+
const bounds = graphics.getLocalBounds()
31+
graphics.pivot.set(
32+
(bounds.x + bounds.width) / 2,
33+
(bounds.y + bounds.height) / 2,
34+
)
35+
}"
4836
/>
4937
</template>
5038
</assets>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<demo mode="full" src="./demo/basic_shapes.vue" />
1+
<demo mode="full" src="./demo/texture-fill.vue" />
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<demo mode="full" :background-alpha="0" src="./demo/animation_basic.vue" />
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<demo mode="full" :background-alpha="0" src="./demo/animation_confetti.vue" />
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<demo mode="full" src="./demo/animation_keyframe.vue" />
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<demo mode="full" src="./demo/animation_physics_particles.vue" />
2+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<demo mode="full" src="./demo/animation_timeline.vue" />
2+
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<script lang="ts" setup>
2+
import type { Container as ContainerElement } from 'pixi.js'
3+
import { whenever } from '@vueuse/core'
4+
import { gsap } from 'gsap'
5+
import { DropShadowFilter } from 'pixi-filters'
6+
import { Graphics, Text } from 'pixi.js'
7+
import { onUnmounted, ref } from 'vue'
8+
import { useScreen } from 'vue3-pixi'
9+
10+
const screen = useScreen()
11+
12+
const dropShadowFilter = new DropShadowFilter({
13+
color: 'black',
14+
alpha: 0.25,
15+
blur: 4,
16+
offset: { x: 0, y: 10 },
17+
})
18+
19+
const words = ['PixiJS', '&', 'GSAP', '💚']
20+
const wrapper = ref<ContainerElement>()
21+
const wordContainers = ref<ContainerElement[]>()
22+
let animation: gsap.core.Tween | null = null
23+
24+
function initial(wrapper: ContainerElement, wordContainers: ContainerElement[]) {
25+
// Calculate spacing
26+
let spacing = 0
27+
wordContainers.forEach((container) => {
28+
const text = container.children.find(child => child instanceof Text) as Text
29+
if (text) {
30+
container.pivot.set(text.width / 2, text.height / 2)
31+
container.x = spacing + text.width / 2
32+
spacing += container.width + 10
33+
}
34+
})
35+
36+
wrapper.pivot.x = spacing / 2
37+
38+
// Start animation
39+
animation = gsap.from(wordContainers, {
40+
y: -100,
41+
alpha: 0,
42+
angle: 'random(-80, 80)',
43+
stagger: 0.1,
44+
duration: 1,
45+
ease: 'back',
46+
yoyo: true,
47+
repeat: -1,
48+
repeatDelay: 1,
49+
})
50+
}
51+
52+
whenever(
53+
() => wordContainers.value && wrapper.value,
54+
() => initial(wrapper.value!, wordContainers.value!),
55+
{ immediate: true }
56+
)
57+
58+
onUnmounted(() => animation?.kill())
59+
</script>
60+
61+
<template>
62+
<assets entry="https://pixijs.com/assets/webfont-loader/Grandstander-ExtraBold.ttf">
63+
<container ref="wrapper" :x="screen.width / 2" :y="screen.height / 2">
64+
<container
65+
v-for="(word, i) in words"
66+
:key="i"
67+
ref="wordContainers"
68+
@effect="container => {
69+
const padding = 20
70+
// Create text
71+
const text = new Text({
72+
text: word,
73+
style: {
74+
fontFamily: 'Grandstander ExtraBold',
75+
fontSize: 36,
76+
fill: 0xFFFFFF,
77+
},
78+
})
79+
80+
// Create rounded rectangle
81+
const box = new Graphics()
82+
.roundRect(
83+
-padding / 2,
84+
-padding / 2,
85+
text.width + padding,
86+
text.height + padding,
87+
8,
88+
)
89+
.fill({ color: 0xED427C })
90+
.stroke({ color: 'white', width: 2 })
91+
92+
box.filters = [dropShadowFilter]
93+
94+
container.pivot.set(text.width / 2, text.height / 2)
95+
// Add box and text to container
96+
container.addChild(box, text)
97+
}"
98+
/>
99+
</container>
100+
</assets>
101+
</template>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { gsap } from 'gsap';
2+
import Physics2DPlugin from 'gsap/Physics2DPlugin';
3+
import { Application, Assets, Graphics, Text } from 'pixi.js';
4+
import { DropShadowFilter } from 'pixi-filters';
5+
6+
gsap.registerPlugin(Physics2DPlugin);
7+
8+
(async () => {
9+
// Create a new application
10+
const app = new Application();
11+
12+
// Initialize the application
13+
await app.init({ background: '#1099bb', resizeTo: window, antialias: true });
14+
await Assets.load(
15+
'https://pixijs.com/assets/webfont-loader/Grandstander-ExtraBold.ttf',
16+
);
17+
18+
// Append the application canvas to the document body
19+
document.body.appendChild(app.canvas);
20+
21+
app.stage.eventMode = 'static'; // Set the stage to static event mode
22+
app.stage.cursor = 'pointer'; // Change cursor to pointer on hover
23+
app.stage.hitArea = app.screen; // Set the hit area to the entire screen
24+
25+
app.stage.addEventListener('click', (event) => {
26+
// Generate a random number of dots
27+
const dotCount = gsap.utils.random(15, 30, 1);
28+
const colors = ['white'];
29+
30+
for (let i = 0; i < dotCount; i++) {
31+
// Create a dot element
32+
const dot = new Graphics()
33+
.circle(0, 0, gsap.utils.random(20, 40))
34+
.fill('white') // Pick a random color
35+
.stroke({ color: 'white', width: 2 }); // Add a white stroke
36+
37+
dot.filters = [
38+
new DropShadowFilter({
39+
color: 'black',
40+
alpha: 0.5,
41+
blur: 4,
42+
offset: { x: 0, y: 5 },
43+
}),
44+
];
45+
46+
app.stage.addChild(dot);
47+
48+
// Set initial position and styles of the dot
49+
gsap.set(dot, {
50+
tint: gsap.utils.random(colors), // Pick a random color
51+
y: event.clientY, // position dot at coordinates of the click
52+
x: event.clientX,
53+
scale: 0, // Start at scale 0
54+
});
55+
56+
// Animate the dot with physics2D
57+
gsap
58+
.timeline({
59+
onComplete: () => dot.destroy(), // Clean up the dot after animation
60+
})
61+
.to(dot, {
62+
scale: gsap.utils.random(0.3, 1), // Random scale for the pop-in effect
63+
duration: 0.02, // Quick pop-in effect
64+
ease: 'power3.out',
65+
})
66+
.to(dot, {
67+
duration: 2,
68+
physics2D: {
69+
velocity: gsap.utils.random(500, 1000), // Random velocity
70+
angle: gsap.utils.random(0, 360), // Random direction
71+
gravity: 1500, // Gravity effect
72+
},
73+
ease: 'none',
74+
}); // Start together with the previous tween
75+
}
76+
});
77+
78+
// add some text to the stage
79+
const text = new Text({
80+
text: 'Click to create confetti',
81+
style: {
82+
fontFamily: 'Grandstander ExtraBold',
83+
fontSize: 50,
84+
fill: 'white',
85+
align: 'center',
86+
},
87+
anchor: 0.5,
88+
x: app.screen.width / 2,
89+
y: app.screen.height / 2 - 50,
90+
});
91+
92+
text.filters = [
93+
new DropShadowFilter({
94+
color: 'black',
95+
alpha: 0.5,
96+
blur: 4,
97+
offset: { x: 0, y: 5 },
98+
}),
99+
];
100+
101+
app.stage.addChild(text);
102+
})();

0 commit comments

Comments
 (0)