旋转轮盘——一个可定制的轮盘,大小不到 30kb,无需 JavaScript 后备。

2025-06-07

旋转轮盘——一个可定制的轮盘,大小不到 30kb,无需 JavaScript 后备。

链接在这里:missingdice.com/spin-the-wheel。非常感谢大家的反馈,希望能够改进它,我已经关注它一周了!

我一直在为桌游玩家搭建一个提供简单工具的网站。由于各种原因,玩家有时需要在线掷骰子翻牌旋转转盘。

该网站就是用于这类简单的事情。

我希望这个网站能够成功,所以我首先研究了竞争对手,并决定——原因我将在另一篇文章中详细说明——如下:

  • 该网站应尽可能方便访问
  • 任何页面都不应大于30kB
  • 每个工具都应该有一个no javascript备用方案

对于此工具,我们需要克服一些有趣的障碍:


令人满意的点击

重要的是,旋转器在旋转时能发出令人满意的咔哒声。

我找到了一个mp3点击器,但即使时长不到1秒,重量也高达7kB。使用它的话,我会超出30kB预算。

我相信有很多巧妙的方法可以减少音频文件的大小。但我选择使用Web Audio APIJavaScript来生成点击,这是我以前从未听说过的东西。

幸运的是,我认识一位合成器爱好者,他向我解释了一些术语。

我找到了有关合成鼓声的这个教程,并调整了踩镲示例以使其适合。

最终结果只是~1.2kB-js还有进一步优化的空间。


创建无 JavaScript 版本

让旋转器在没有的情况下工作js非常简单。

如果浏览器已禁用,则单击提交表单JavaScript而不是生成并旋转轮子……client-sidespin the wheel

然后服务器:

  • 使用用户的自定义值构建一个微调器
  • 随机选出一名获胜者
  • 提前生成一个旋转轮子的 CSS 动画
  • 将 html 发送回客户端

效果出奇地好。

我使用Netlify Functions实现了这一点,因此我不会为不使用该网站的极少数人运行整个服务器js


动画 SVG

虽然 SVG 动画通常没什么问题,但有些浏览器(例如 Safari)处理起来确实很费劲。经过一番尝试,最终发现最好的解决办法就是为每个动画组件使用单独的 SVG,并将它们分别放在各自的 SVG 文件中<div>,然后再进行动画处理<div>


点击时机

旋转器以不同的速率、持续时间和随机旋转次数旋转——这样它就会保持令人惊讶和戏剧性。

为了使旋转真正令人满意,它需要在顶部有一个小小的计时器。(就像游戏节目“命运之轮”一样)。

这意味着在轮盘的边缘放置“针”,每当“碰到”一个“针”时,就会播放动画。

出于性能原因,我认为最好提前计算动画(和点击声音)的时间。

这真是一项非常复杂的任务,学习了三天微积分之后我就放弃了。

相反,它会使用requestAnimationFrame并测量旋转器的当前旋转角度。如果旋转角度在特定范围内,就会发出咔哒声。

这种方法虽然有效,但确实会犯错误。

这也意味着该no-javascript版本没有股票动画。


旋转着数千个值

一个问题是允许人们向微调器添加 1000 个值。

我认为有一个用例,某人可能想要粘贴整个电子表格的值,然后随机选择一个。

所以,我决定使用 a<textarea>作为输入,每个新值占一行。这样,如果用户粘贴一个逗号分隔的列表,它会在生成轮子之前重新格式化它。

这里最大的问题是性能。

为了使其工作,<svg>随着更多值的添加,微调器变得越来越简单。

  • 图案被移除。
  • 轮辋上的销钉数量上限为60
  • 文本路径变得更简单。

我只在我那台新买的电脑上测试过,不过在大约这个6000数值下运行正常。欢迎大家测试一下,然后告诉我结果!


需要改进的地方!

  • 整体外观和感觉可以进一步完善 — — 特别是在替代配色方案上。
  • 可以对点击声音进行调整。
  • 找到一种提前测量点击动画的准确方法将是一件很棒的事情。
  • 制作可嵌入的定制车轮<iframe>会很酷。

请告诉我您的想法以及可以改进的地方?

文章来源:https://dev.to/shadowfaxrodeo/spin-the-wheel-a-customized-roulette-wheel-in-less-that-30kb-with-a-no-javascript-fallback-45ma
PREV
如何让你的函数式 React 组件表现更好(使用 useCallback 和 memo)
NEXT
如何从头开始构建 Node.Js 项目?