react 椭圆形转盘 点击左右箭头 图片位置变换

效果图:

 目前已实现功能 :图片围绕椭圆排列,图片大小视觉效果,正中间图片为选中状态,点击左右箭头图片位置依次变化;

实现思路:

图片排列 :通过计算角度和弧度,计算出每个元素的定位left top值;

图片大小: 通过对比top值,设置图片的transfrom scal值

左右箭头:图片之间间距相等,每次点击会更新元素位置数据 left top值

高亮图片:判断位置,切换图片;

上代码:

import React, { useState, useEffect} from 'react';
import img1 from '../../assets/images/1im.png'; //车辆
import img2 from '../../assets/images/2im.png'; //供电
import img3 from '../../assets/images/3im.png'; //土建
import img4 from '../../assets/images/4im.png'; //信号
import img5 from '../../assets/images/5im.png'; //通信
import img6 from '../../assets/images/6im.png'; //机电
import img7 from '../../assets/images/7im.png'; //线路
import img8 from '../../assets/images/8im.png'; //AFC
// 点击切换高亮图
import img1_2 from '../../assets/images/1-2.png';
import img2_2 from '../../assets/images/2-2.png';
import img3_2 from '../../assets/images/3-2.png';
import img4_2 from '../../assets/images/4-2.png';
import img5_2 from '../../assets/images/5-2.png';
import img6_2 from '../../assets/images/6-2.png';
import img7_2 from '../../assets/images/7-2.png';
import img8_2 from '../../assets/images/8-2.png';
import './turntable.scss';

const imgs = [img5, img3, img8, img7, img6, img4, img2, img1];
const imgs1 = [img5_2, img3_2, img8_2, img7_2, img6_2, img4_2, img2_2, img1_2];
// 图片比例缩放
const setScale = (num) => {
  if (num === 84) {
    return 0.9;
  } else if (num === 20) {
    return 0.8;
  } else if (num === 44) {
    return 0.7;
  } else if (num === 70) {
    return 0.65;
  } else if (num === 110) {
    return 1;
  }
};
const Turntable = () => {
  const [nodes, setNodes] = useState([]);
  const [speeds, setSpeed] = useState(1);
  const width = 1126;
  const height = 180;
  const leng = 8;
  const domWidth = 170;
  const domHeight = 180;
  function carousel() {
    const arr = [];
    //中心点横坐标
    var dotLeft = width / 2 - domWidth / 2;
    //中心点纵坐标
    var dotTop = height / 2 - domHeight / 2 + 20;
    //椭圆长边
    let a = width / 2;
    //椭圆短边
    let b = height / 2;
    //每一个BOX对应的角度;
    var avd = 360 / leng;
    //每一个BOX对应的弧度;
    var ahd = (avd * Math.PI) / 180;
    //运动距离,即运动的弧度数;
    var ainhd1 = (speeds * Math.PI) / 180;
    var ainhd = speeds * ahd;
    for (let i = 0; i < leng; i++) {
      let left = Math.round(Math.sin(ahd * i + ainhd) * a + dotLeft);
      let top = Math.round(Math.cos(ahd * i + ainhd) * b + dotTop);
      let obj = {
        left: left,
        top: top,
        img: imgs[i],
        img1: imgs1[i],
        scale: setScale(Math.floor(Math.abs(top)))
      };
      arr.push(obj);
    }
    setNodes(arr);
  }

  useEffect(() => {
    carousel(); //旋转
  }, [speeds]);
  // 点击左右箭头
  const checkImg = (a) => {
    if (a === 'right') {
      let speed = speeds < 8 ? speeds : 1;
      setSpeed(speed + 1);
    }
    if (a === 'left') {
      let speed = speeds > -8 ? speeds : 1;
      setSpeed(speed - 1);
    }
  };
  return (
    <div className="turntable">
      <div className="leftRow" onClick={() => checkImg('left')}></div>
      <div className="centerTurn">
        {nodes.map((res, index) => {
          const img = res.top === 110 ? res?.img : res?.img1;
          let styleobj = {
            top: res.top,
            left: res.left,
            transform: `scale(${res.scale})`
          };
          return (
            <div
              className="zhunpng"
              style={styleobj}
              key={index}
              onClick={() => move(res)}
            >
              <img src={img} className="zhunimg" alt="" />
            </div>
          );
        })}
      </div>
      <div className="rightRow" onClick={() => checkImg('right')}></div>
    </div>
  );
};
export default Turntable;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值