开发三十个纯前端微信小程序小工具之幸运转盘(30/1)
一个开箱即用的幸运转盘,支持自定义转盘内容、转盘颜色。
幸运转盘页面截图
转盘的实现功能在互联网上十分常见,各类现成工具比比皆是。通过代码调研发现,多数解决方案采用预制转盘图片的方式开发,这种方法最为简便。此外也存在基于Canvas的实现方案,但未能找到CSS+JS组合的源码参考。得益于AI辅助开发工具的效率提升,最终选择通过AI协助开发了一套基于CSS+JS的小程序转盘实现方案。
小程序基于uniapp框架开发。由于完整代码量较大,这里仅展示核心代码片段,完整源码将通过文末git链接提供。
在CSS实现方案上,最初尝试采用覆盖层方案,但发现首尾元素的层级会相互冲突,无法妥善处理,只得放弃该方案。AI曾建议使用SVG标签方案,但因小程序不支持直接使用SVG标签而作罢。最终采用clip-path属性解决方案,其原理是通过创建多边形并隐藏超出圆形范围的部分,从而实现所需的扇形效果。
这里是让AI转成了html 代码直观一点
<div class="wheel-wrapper" id="wheel">
<div class="wheel-section" style="background-color:#1A535C;clip-path:polygon(50% 50%, 71.85059167225252% -17.249206267230306%, 120.71% 49.999999999999986%);">
<div class="section-text" style="transform:translate(-50%, -50%) translateX(84.0px) translateY(-61.0px) rotate(414deg);">
<span>选项五</span>
</div>
</div>
</div>
主要就是clip-path:polygon(50% 50%, 71.85059167225252% -17.249206267230306%, 120.71% 49.999999999999986%); 这个样式 通过计算每一个的多边形位置拼一个圆出来
转盘的形状出来了,其他就水到渠成了,这里就不做多于的说明了
接下来展示核心代码片段
// 获取扇形区域样式 - 使用CSS变量和clip-path创建精确扇形
const getSectionStyle = (index, option) => {
const count = currentWheel.options.length;
const angle = 360 / count;
const startAngle = index * angle;
const color = option.color || getDefaultColor(index);
// 计算扇形的clip-path路径
const radius = 70.71; // 相对于父元素的百分比
const centerX = 50; // 中心点X坐标
const centerY = 50; // 中心点Y坐标
// 计算扇形的起始点和结束点坐标
const startRad = (startAngle * Math.PI) / 180;
const endRad = ((startAngle + angle) * Math.PI) / 180;
const startX = centerX + radius * Math.cos(startRad);
const startY = centerY + radius * Math.sin(startRad);
const endX = centerX + radius * Math.cos(endRad);
const endY = centerY + radius * Math.sin(endRad);
// 创建clip-path多边形
const clipPath = `polygon(${centerX}% ${centerY}%, ${startX}% ${startY}%, ${endX}% ${endY}%)`;
return {
position: "absolute",
width: "100%",
height: "100%",
backgroundColor: color,
clipPath: clipPath,
transformOrigin: "center",
};
};
// 计算文本样式
const getSectionTextStyle = (index) => {
const count = currentWheel.options.length;
const angle = 360 / count;
const startAngle = index * angle;
const textAngle = startAngle + angle / 2;
// 计算文本位置,确保在扇形中间,使用更大的radius值让文本离中心更远
const radius = 200; // 文本距离中心的距离(rpx)
const radians = (textAngle * Math.PI) / 180;
const x = radius * Math.cos(radians);
const y = radius * Math.sin(radians);
return {
position: "absolute",
left: "50%",
top: "50%",
transform: `translate(-50%, -50%) translateX(${x}rpx) translateY(${y}rpx) rotate(${
textAngle + 90
}deg)`,
fontSize: "32rpx",
color: "#fff",
fontWeight: "bold",
textAlign: "center",
whiteSpace: "nowrap",
textShadow: "1rpx 1rpx 2rpx rgba(0,0,0,0.3)",
writingMode: "vertical-rl",
zIndex: 1,
maxWidth: "150rpx",
};
};
最后附上我的源码链接
链接:https://gitee.***/chenchongk/tool-box-zhuanpan.git
有兴趣的同学可以体验一下我的小程序: 口袋工具包
打代码不易,如果对你有帮助,也希望帮我增加一下小程序日活