如何写一个转盘

需求描述

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

实现

思路

核心实现机制:

  • 外部的容器,也就是圆周,采用相对定位
  • 每个数字块的定位采用绝对定位 + 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>

效果展示

相关推荐
我是一只小青蛙88818 小时前
手撕C++STL的list实现
开发语言·c++·list
顺心而行...18 小时前
安装 ubuntu 24.04 LTS 单系统教程
开发语言
yaoxin52112318 小时前
295. Java Stream API - 选择适用于并行计算的 BinaryOperator
java·开发语言
CHHC188018 小时前
golang 项目依赖备份
开发语言·后端·golang
冬至喵喵18 小时前
RoaringBitmap与传统Bitmap
java·开发语言
Front思18 小时前
Vue3仿美团实现骑手路线规划
开发语言·前端·javascript
徐同保18 小时前
Nano Banana AI 绘画创作前端代码(使用claude code编写)
前端
Ulyanov18 小时前
PyVista与Tkinter桌面级3D可视化应用实战
开发语言·前端·python·3d·信息可视化·tkinter·gui开发
计算机程序设计小李同学18 小时前
基于Web和Android的漫画阅读平台
java·前端·vue.js·spring boot·后端·uniapp
lkbhua莱克瓦2419 小时前
HTML与CSS核心概念详解
前端·笔记·html·javaweb