用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),半径200ctx.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>