用Canvas 画布样式实现旋转的阴阳图

用Canvas 画布样式实现旋转的阴阳图
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas八卦图动画</title>
    <style>
        /* 重置所有元素的默认样式 */
        * {
      
      
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        
        /* Canvas 画布样式设置 */
        canvas {
      
      
            display: block;  /* 块级显示消除底部间隙 */
            margin: 100px auto;  /* 上下100px,左右自动居中 */
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);  /* 添加柔和阴影 */
            border-radius: 50%;  /* 圆形边框 */
        }
    </style>
</head>
<body>
    <!-- 创建画布,设置宽高为400像素 -->
    <canvas id="baguaCanvas" width="400" height="400"></canvas>
    <script>
        // 获取画布和绘图上下文
        const canvas = document.getElementById('baguaCanvas');
        const ctx = canvas.getContext('2d');
        let rotation = 0;  // 初始化旋转角度

        /**
         * 绘制八卦图的主函数
         * 包含了完整的绘制步骤:背景圆、阴阳分割、大小圆的绘制
         */
        function drawBagua() {
      
      
            // 清除整个画布
            ctx.clearRect(0, 0, 400, 400);
            ctx.save();  // 保存当前绘图状态
            
            // 设置旋转中心点和旋转角度
            ctx.translate(200, 200);  // 移动到画布中心
            ctx.rotate(rotation);     // 应用旋转
            ctx.translate(-200, -200);  // 移回原位置

            // 绘制背景圆形裁剪区域
            ctx.beginPath();
            ctx.arc(200, 200, 200, 0, Math.PI * 2);  // 圆心(200,200),半径200
            ctx.clip();  // 设置裁剪区域,确保图形为圆形

            // 绘制阴阳分割的左右两半
            ctx.fillStyle = '#000';  // 左半边黑色
            ctx.fillRect(0, 0, 200, 400);
            ctx.fillStyle = '#fff';  // 右半边白色
            ctx.fillRect(200, 0, 200, 400);

            // 绘制上方黑色大圆(阴)
            ctx.beginPath();
            ctx.arc(200, 100, 100, 0, Math.PI * 2);
            ctx.fillStyle = '#000';
            ctx.fill();

            // 绘制下方白色大圆(阳)
            ctx.beginPath();
            ctx.arc(200, 300, 100, 0, Math.PI * 2);
            ctx.fillStyle = '#fff';
            ctx.fill();

            // 绘制阴阳眼(上白下黑)
            ctx.beginPath();
            ctx.arc(200, 100, 20, 0, Math.PI * 2);  // 上方白色小圆
            ctx.fillStyle = '#fff';
            ctx.fill();

            ctx.beginPath();
            ctx.arc(200, 300, 20, 0, Math.PI * 2);  // 下方黑色小圆
            ctx.fillStyle = '#000';
            ctx.fill();

            ctx.restore();  // 恢复之前保存的绘图状态
        }

        /**
         * 基础动画循环函数
         * 每帧更新旋转角度并重绘
         */
        function animate() {
      
      
            rotation += 0.02;  // 每帧旋转0.02弧度
            drawBagua();
            requestAnimationFrame(animate);
        }

        // 鼠标悬停事件控制
        let isAnimating = true;  // 动画状态标志
        canvas.addEventListener('mouseenter', () => isAnimating = false);  // 鼠标进入暂停
        canvas.addEventListener('mouseleave', () => isAnimating = true);   // 鼠标离开继续

        /**
         * 优化后的动画循环函数
         * 增加了动画状态控制,提高性能
         */
        function optimizedAnimate() {
      
      
            if (isAnimating) {
      
        // 仅在动画激活状态下更新
                rotation += 0.02;
                drawBagua();
            }
            requestAnimationFrame(optimizedAnimate);
        }

        // 启动优化后的动画循环
        optimizedAnimate();
    </script>
</body>
</html>