用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>