vue如何实现树叶飘落
Vue 实现树叶飘落效果
使用 CSS 动画和动态组件
在 Vue 中实现树叶飘落效果可以通过 CSS 动画结合动态组件的方式完成。创建一个树叶组件,使用 CSS 定义飘落动画路径。

<template>
<div class="leaf" :style="leafStyle"></div>
</template>
<script>
export default {
props: {
delay: {
type: Number,
default: 0
}
},
computed: {
leafStyle() {
return {
left: `${Math.random() * 100}%`,
animationDelay: `${this.delay}s`
}
}
}
}
</script>
<style>
.leaf {
position: fixed;
top: -50px;
width: 30px;
height: 30px;
background-image: url('leaf.png');
background-size: contain;
animation: falling 10s linear infinite;
}
@keyframes falling {
0% {
transform: translate(0, 0) rotate(0deg);
}
100% {
transform: translate(calc(-50px + 100px * var(--random-x)), calc(100vh + 50px)) rotate(360deg);
}
}
</style>
使用 GSAP 动画库
对于更复杂的路径动画,可以使用 GSAP 库实现更自然的飘落效果。安装 GSAP 后创建动画控制器。

import { gsap } from 'gsap'
export default {
mounted() {
this.animateLeaf()
},
methods: {
animateLeaf() {
gsap.to(this.$el, {
duration: 10 + Math.random() * 5,
y: window.innerHeight + 100,
x: () => Math.random() * 200 - 100,
rotation: 360,
ease: "none",
onComplete: () => {
this.resetPosition()
this.animateLeaf()
}
})
},
resetPosition() {
gsap.set(this.$el, {
y: -100,
x: Math.random() * window.innerWidth
})
}
}
}
使用 Canvas 绘制
对于大量树叶效果,使用 Canvas 性能更优。创建一个 Canvas 组件并实现绘制逻辑。
export default {
data() {
return {
leaves: [],
ctx: null
}
},
mounted() {
this.initCanvas()
this.generateLeaves(20)
requestAnimationFrame(this.animate)
},
methods: {
initCanvas() {
const canvas = this.$refs.canvas
canvas.width = window.innerWidth
canvas.height = window.innerHeight
this.ctx = canvas.getContext('2d')
},
generateLeaves(count) {
for (let i = 0; i < count; i++) {
this.leaves.push({
x: Math.random() * this.$refs.canvas.width,
y: -50 - Math.random() * 200,
speed: 1 + Math.random() * 3,
rotation: 0,
rotationSpeed: Math.random() * 0.2 - 0.1,
size: 20 + Math.random() * 20
})
}
},
animate() {
this.ctx.clearRect(0, 0, this.$refs.canvas.width, this.$refs.canvas.height)
this.leaves.forEach(leaf => {
leaf.y += leaf.speed
leaf.x += Math.sin(leaf.y * 0.01) * 2
leaf.rotation += leaf.rotationSpeed
this.ctx.save()
this.ctx.translate(leaf.x, leaf.y)
this.ctx.rotate(leaf.rotation)
this.ctx.drawImage(this.leafImage, -leaf.size/2, -leaf.size/2, leaf.size, leaf.size)
this.ctx.restore()
if (leaf.y > this.$refs.canvas.height) {
leaf.y = -50
leaf.x = Math.random() * this.$refs.canvas.width
}
})
requestAnimationFrame(this.animate)
}
}
}
性能优化技巧
对于大量动画元素,使用 requestAnimationFrame 比 CSS 动画性能更好。限制同时显示的树叶数量,回收超出屏幕的树叶对象。
考虑使用 WebGL 或第三方库如 Three.js 实现更复杂的 3D 飘落效果。对于移动端,减少动画元素数量并测试性能表现。






