bingbingyihao 2023-03-27 11:17 采纳率: 100%
浏览 24
已结题

CSS动画的重复播放及保持原效果

遇到的问题

无法让动画重复播放,每次播放结束后都无法继续播放
如果设置为可以多次播放,则又无法保持原状态(设置多次播放是通过重写了animation属性实现;一旦重写,这个 forwards 就没用了)

相关代码

转盘小游戏,Vue3代码

<template>
    <div id="app">
        <canvas id="canvas" :width="data.radius" :height="data.radius" class="container"></canvas>
        <span class="play" @click="play">点击开启转盘</span>
    </div>
</template>

<script>
import { onBeforeMount, onMounted, reactive } from "vue";

export default {
    name: "App",
    setup() {
        onBeforeMount(() => {
            const widthOfDevice = document.body.clientWidth;
            data.radius = widthOfDevice * 0.8;
        });
        const data = reactive({
            awardList: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
            radius: 200
        });

        function play() {
            const randomDeg = 360 * 8 + parseInt(Math.random() * 360 * 2);
            document.styleSheets[0].insertRule(
                `@keyframes run-rotate {
                    from {
                        transform: rotateZ(0deg);
                    }
                    to {
                        transform: rotateZ(${randomDeg}deg);
                    }
                }`,
            );
        }

        onMounted(() => {
            const myCanvas = document.getElementById("canvas");
            draw(myCanvas);
        });

        const randomColorList = ["#4169e199", "#fa807299", "#98fb9899", "#f5deb399", "#dda0dd99"];
        function draw(myCanvas) {
            const ctx = myCanvas.getContext("2d");
            ctx.translate(data.radius / 2, data.radius / 2);
            for (var i = 0; i < 10; i++) {
                ctx.beginPath();
                ctx.fillStyle = "#000000";
                ctx.font = "20px 行楷";
                for (var j = 0; j < 10; j++) {
                    ctx.fillText(data.awardList[i], data.radius / 2 * 0.6, 46);
                }
                ctx.fillStyle = randomColorList[i % 5];
                ctx.moveTo(0, 0);
                ctx.arc(0, 0, data.radius / 2, (0 * Math.PI) / 180, (36 * Math.PI) / 180);
                ctx.rotate((36 * Math.PI) / 180);
                ctx.fill();
                ctx.closePath();
            }
        }

        return {
            data,
            play,
        };
    },
};
</script>

<style>
* {
    padding: 0;
    margin: 0;
}

/* 容器样式 */
.container {
    width: 80vw;
    height: 80vw;
    margin-left: 10vw;
    margin-top: 10vw;
    border-radius: 50%;
    animation: run-rotate 3s ease-in-out 1;
    animation-fill-mode: forwards;
}

/* 开启按钮样式 */
.play {
    display: block;
    width: 40vw;
    height: 10vw;
    line-height: 10vw;
    margin-left: 30vw;
    margin-top: 10vw;
    cursor: pointer;
    color: crimson;
    text-align: center;
    border: 1px solid crimson;
    font-size: 20px;
    border-radius: 4vw;
}
</style>

img

  • 写回答

1条回答 默认 最新

  • 程序yang 全栈领域优质创作者 2023-03-27 11:59
    关注

    参考这样改改看看行不行

    <canvas ref="myCanvas" :width="data.radius" :height="data.radius" class="container run-rotate"></canvas>
    
    function play() {
          // 移除 run-rotate class,以重置动画状态
          this.$refs.myCanvas.classList.remove("run-rotate");
    
          const randomDeg = 360 * 8 + parseInt(Math.random() * 360 * 2);
          document.styleSheets[0].insertRule(
            `@keyframes run-rotate {
              from {
                transform: rotateZ(0deg);
              }
              to {
                transform: rotateZ(${randomDeg}deg);
              }
            }`
          );
    
          // 使用 setTimeout 函数,延迟一段时间后再次添加 run-rotate class,以触发动画的重复播放
          setTimeout(() => {
            this.$refs.myCanvas.classList.add("run-rotate");
          }, 100);
        }
    
        onMounted(() => {
          const myCanvas = this.$refs.myCanvas;
          draw(myCanvas);
        });
    
    .run-rotate {
      animation: run-rotate 3s ease-in-out 1;
      animation-fill-mode: forwards;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 4月4日
  • 已采纳回答 3月27日
  • 创建了问题 3月27日

悬赏问题

  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。