用超简单的js实现【游戏摇杆特效】

309 阅读1分钟

该示例基于uniapp

先上效果图

SDGIF_Rusult_1.gif

实现

// data
data (){
  return {
    transitionObj: { l: 0, t: 0 }, // 当前摇杆定位
    initXY: null, // 原始摇杆xy存储对象
    timer: null,
  }
}

// dom
<view class="rocker">
  <view class="front" @touchstart="onRockerStart" @touchend="onRockerEnd" @touchmove="onRockerMove" @touchcancel="onRockerEnd" :style="{ left: transitionObj.l + 'rpx', top: transitionObj.t + 'rpx' }" />
</view>

// scss
.rocker {
  position: absolute;
  z-index: 20;
  width: 120rpx;
  height: 120rpx;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 50%;
  bottom: 35vh;
  left: 12vw;

  .front {
    position: absolute;
    z-index: 21;
    width: 60rpx;
    height: 60rpx;
    background: rgba(255, 255, 255, 0.25);
    border-radius: 50%;
    margin-top: 30rpx;
    margin-left: 30rpx;
    top: 0;
    left: 0;
    // transform: translate(-50%, -50%);
    transition: none 0s ease 0s;
  }
}

onRockerStart

onRockerStart(){
  if (!this.initXY) {
    const query = uni.createSelectorQuery().in(this);
      query
        .select(".front")
        .boundingClientRect((data) => {
            // 记录摇杆操作元素中心位置 (+15: 原点宽度60,圆心需偏量加上半径)
            this.initXY = {
              x: data.left + 15,
              y: data.top + 15,
            };
       })
       .exec();
  }
}

onRockerMove

onRockerMove: function (e) {
  if (this.timer) return; 
  const target = e.touches[0];
  let y = target.pageY - this.initXY.y;  // 鼠标移动y轴距离
  let x = target.pageX - this.initXY.x;  // 鼠标移动x轴距离

  const powV = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));  // 斜边长度 (勾股)
  
  // 1.超范围限制   60: 大原点的半径,即120rpx/2;
  // 2.当鼠标移动范围大于60时,需要等比处理摇杆中心点实际移动距离
  // 3.如图1所示,根据xxx数学定理:
  //   3.1 小三角侧边(y) : 大三角底边(y) = 实际移动(r) : 斜长(powV)
  //   3.2 小三角侧边(x) : 大三角侧边(x) = 实际移动(r) : 斜长(powV)
  const r = 60;
  if (powV > r) {
    y = r / powV * y;
    x = r / powV * x;
  }

  this.transitionObj = { t: y, l: x };

  // 节流
  this.timer = setTimeout(() => {
    clearTimeout(this.timer);
    this.timer = null;
  }, 50);
},
  • 图1

无标题.png

onRockerEnd

// 清除定时器 并 重置元素位置
onRockerEnd: function (e) {
  console.log("结束");
  this.transitionObj = { l: 0, t: 0 };
  clearTimeout(this.timer);
  this.timer = null;
},