如何写一个转盘

需求描述

  • 实现一个圆形转盘组件,转盘上的元素均匀分布,同时保持转盘元素的水平轴始终指向圆心。保证转盘最左边的元素是水平放置,正常展示。
  • 点击地下一排按钮,则转盘上对应的元素转到最左边。

实现

思路

核心实现机制:

  • 外部的容器,也就是圆周,采用相对定位
  • 每个数字块的定位采用绝对定位 + transform,旋转好角度后有序放在圆周上

交互逻辑:

  • 点击底部按钮时,计算目标数字所需旋转角度
  • 转盘通过 CSS transform: rotate() 实现整体旋转
  • 通过 CSS transition 实现平滑旋转动画

页面结构

什么是静态的?

  • 转盘的形状
  • 转盘元素的形状
  • 转盘元素相对于圆盘水平线的角度

什么是动态的?

  • 圆盘的旋转角度

什么是要算的?

  • 圆盘的旋转角度
  • 转盘元素相对于圆盘水平线的角度

动态的和要算的要写成变量或者方法

实现机制

不要去想转了 多少度,不要想成计算;而是应该每个位置对应一个唯一的旋转角度,要想成映射

计算转盘元素相对于圆盘水平线的角度,包含三个关键步骤:

  • rotate(角度) - 按序分布在圆周上
  • translate(-150px) - 将数字移到圆周上,这里应为要保证最左边的元素是我们要展示的元素,所以是负数
  • translate(-150px) translate(-50%)确保圆盘元素的中心在圆周的上
javascript 复制代码
// 计算每个数字块的位置和角
getItemStyle(index) {
  const anglePerSector = 360 / this.totalSectors;
  const rotateAngle = index * anglePerSector;
  return {
    transform: `rotate(${rotateAngle}deg) translate(-150px) translate(-50%) translateY(-50%)`,
  };
},

旋转转盘的方法,也就是要算出目标位置对应的角度是多少

java 复制代码
// 计算按钮点击后转盘的旋转角度
rotateToNumber(index) {
    const anglePerSector = 360 / this.totalSectors;
    const targetAngle = index * anglePerSector;
    // 为了让目标数字转到最左边,我们需要相应调整角度
    this.rotation = -targetAngle;
},

组件代码

vue 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <script src="./js/vue.min.js"></script>
    <title>Title</title>
</head>
<body>
<div id="vue_root">
  <div class="wheel-container">
    <!-- 转盘 -->
    <div class="wheel" :style="{ transform: `rotate(${rotation}deg)` }">
      <div v-for="(item, index) in numbers" :key="index" class="wheel-item" :style="getItemStyle(index)">
        {{ item }}
      </div>
    </div>

    <!-- 数字按钮 -->
    <div class="buttons">
      <button v-for="(item, index) in numbers" :key="index" @click="rotateToNumber(index)">
        {{ item }}
      </button>
    </div>
  </div>
</div>
</body>
<script>
  let vm = new Vue({
    el: "#vue_root",
    data() {
      return {
        numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9], // 转盘上的数字
        rotation: 0, // 转盘的旋转角度
        totalSectors: 9, // 转盘分为9个部分
      };
    },
    methods: {
      // 计算按钮点击后转盘的旋转角度
      rotateToNumber(index) {
        const anglePerSector = 360 / this.totalSectors;
        const targetAngle = index * anglePerSector;
        // 为了让目标数字转到最左边,我们需要相应调整角度
        this.rotation = -targetAngle;
      },
      // 计算每个数字块的位置和角
      getItemStyle(index) {
        const anglePerSector = 360 / this.totalSectors;
        const rotateAngle = index * anglePerSector;
        return {
          transform: `rotate(${rotateAngle}deg) translate(-150px) translate(-50%) translateY(-50%)`,
        };
      },
    },
  })
</script>
<style>
  .wheel-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin-top: 50px;
  }

  .wheel {
    width: 300px;
    height: 300px;
    border-radius: 50%;
    border: 2px solid #000;
    position: relative;
    /*left: 50%;*/
    margin-bottom: 20px;
    transition: transform 1s ease-in-out; /* 转盘旋转时的动画效果 */
  }

  .wheel-item {
    position: absolute;
    top: 50%;
    left: 50%;
    transform-origin: 0 0; /* 以左上角为原点进行旋转 */
    width: 30px;
    height: 30px;
    background-color: #f1c40f;
    text-align: center;
    line-height: 30px;
    border-radius: 50%;
  }

  .buttons {
    display: flex;
    justify-content: center;
  }

  button {
    margin: 0 5px;
    padding: 10px 20px;
    background-color: #3498db;
    color: white;
    border: none;
    cursor: pointer;
  }

  button:hover {
    background-color: #2980b9;
  }
</style>
</html>

效果展示

相关推荐
包饭厅咸鱼6 分钟前
QT----使用onnxRuntime运行图像分类模型
开发语言·qt·分类
华仔啊12 分钟前
Vue3+CSS实现一个非常丝滑的 input 标签上浮动画,设计师看了都点赞
前端·css·vue.js
北海道浪子16 分钟前
[免费送$1000]ClaudeCode、Codex等AI模型在开发中的使用
前端·人工智能·后端
明月与玄武22 分钟前
2025 前端框架决战:Vue 与 React 分析优缺点及使用场景!
前端·vue.js·react.js
Matlab程序猿小助手33 分钟前
【MATLAB源码-第303期】基于matlab的蒲公英优化算法(DO)机器人栅格路径规划,输出做短路径图和适应度曲线.
开发语言·算法·matlab·机器人·kmeans
不爱编程的小九九33 分钟前
小九源码-springboot097-java付费自习室管理系统
java·开发语言·spring boot
无盐海38 分钟前
XSS漏洞攻击 (跨站脚本攻击)
前端·xss
不一样的少年_43 分钟前
1024程序员节:用不到100行代码做个“代码雨屏保”装X神器(附源码)
前端·javascript·浏览器
云知谷1 小时前
【经典书籍】C++ Primer 第16章模板与泛型编程精华讲解
c语言·开发语言·c++·软件工程·团队开发
阿奇__1 小时前
el-table默认排序设置
前端·javascript·vue.js