| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- <template>
- <view class="container">
- <view
- v-for="(ball, index) in balls"
- :key="index"
- :class="['ball', ball.colorClass]"
- :style="ball.style"
- @animationend="handleAnimationEnd(index)"
- >
- <text>{{ ball.content }}</text>
- </view>
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- balls: [], // 存储小球信息的数组
- animationFrames: [], // 存储每个小球的动画帧信息
- };
- },
- mounted() {
- this.initBalls();
- this.startAnimations();
- },
- methods: {
- initBalls() {
- const numBalls = 10; // 小球数量
- for (let i = 0; i < numBalls; i++) {
- this.balls.push({
- colorClass: this.getRandomColorClass(), // 随机颜色类
- content: `Ball ${i + 1}`, // 自定义内容
- style: {
- position: 'absolute',
- left: `${Math.random() * window.innerWidth}px`, // 随机初始位置X
- top: `${Math.random() * window.innerHeight}px`, // 随机初始位置Y
- transform: `translate(-50%, -50%)`, // 居中内容
- },
- direction: { x: Math.random() * 2 - 1, y: Math.random() * 2 - 1 }, // 随机方向
- speed: Math.random() * 2 + 1, // 随机速度
- });
- }
- },
- getRandomColorClass() {
- // 根据需要返回随机颜色类名,这里简化为几个预设类
- const colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange'];
- return colors[Math.floor(Math.random() * colors.length)];
- },
- startAnimations() {
- // 为每个小球启动动画
- this.balls.forEach((ball, index) => {
- setTimeout(() => {
- this.animateBall(index);
- }, Math.random() * 2000); // 随机延迟开始动画
- });
- },
- animateBall(index) {
- const ball = this.balls[index];
- let newLeft = parseFloat(ball.style.left) + ball.direction.x * ball.speed;
- let newTop = parseFloat(ball.style.top) + ball.direction.y * ball.speed;
- // 碰撞检测(边界反弹)
- if (newLeft < 0 || newLeft > window.innerWidth - 50) { // 50是假设的小球宽度
- ball.direction.x = -ball.direction.x;
- newLeft += ball.direction.x * ball.speed * 2; // 反弹后调整位置,避免抖动
- }
- if (newTop < 0 || newTop > window.innerHeight - 50) { // 50是假设的小球高度
- ball.direction.y = -ball.direction.y;
- newTop += ball.direction.y * ball.speed * 2; // 反弹后调整位置,避免抖动
- }
- ball.style.left = `${newLeft}px`;
- ball.style.top = `${newTop}px`;
- // 使用requestAnimationFrame进行持续动画
- this.animationFrames[index] = requestAnimationFrame(() => {
- this.animateBall(index);
- });
- // 可选:为动画添加结束处理(例如,当小球需要停止或改变方向时)
- // 但在这个例子中,我们让小球持续运动,所以不需要特别处理动画结束
- },
- handleAnimationEnd(index) {
- // 这个方法在这个例子中未使用,因为我们是用requestAnimationFrame控制的动画
- // 如果你使用CSS动画,这个方法可以用来处理动画结束后的逻辑
- },
- },
- beforeDestroy() {
- // 组件销毁前取消所有动画帧请求
- this.animationFrames.forEach(cancelAnimationFrame);
- },
- };
- </script>
|