vue3 刻度尺 联动

目前没找到vue3 的刻度尺插件,在网上找了一个用canvas写的,改改东西,就满足要求了

这是ruler.js文件,封装成js文件,调用即可

效果

 

export let ruler = {
  /**
   * 初始化刻度尺插件
   * @el 容器 String
   * @height 刻度尺高度 Number
   * @maxScale 最大刻度 Number
   * @startValue 开始的值 Number
   * @region 区间 Array
   * @background 刻度尺背景颜色 String
   * @color 刻度线和字体的颜色 String
   * @markColor  中心刻度标记颜色 String
   * @isConstant 是否不断地获取值 Boolean
   * @minScale 滑动的最小刻度值 Number
   * @success(res) 滑动结束后的回调 Function
   * */
  initPlugin: function (params) {
    var initParams = {
      el: params.el,
      height: params.height || 60,
      maxScale: params.maxScale || 87,
      startValue: params.startValue || 20,
      region: params.region || false,
      background: params.background || false,
      color: params.color || false,
      markColor: params.markColor || "#FFCC33",
      isConstant: params.isConstant || false,
      startI: params.startI,
      minScale:params.minScale || 1
    };

    if (!initParams.el) {
      console.warn("没有容器元素的参数");
      return false;
    }

    var rulerWrap = document.getElementById(initParams.el); //获取容器
    rulerWrap.style.height =
      initParams.height < 12 ? 12 + "px" : initParams.height + "px";

    //最大刻度的小值是12
    initParams.maxScale = initParams.maxScale < 12 ? 12 : initParams.maxScale;

    if (initParams.startValue > initParams.maxScale) {
      initParams.startValue = initParams.maxScale;
    }

    var minSildeNum = initParams.minScale; //最小滑动的值
    var maxSildeNum = initParams.maxScale; //最大滑动的值

    if (initParams.region) {
      minSildeNum = Math.floor(initParams.region[0]);
      maxSildeNum = Math.floor(initParams.region[1]);
    }

    var count = initParams.startValue; //初始值

    var winWidth = rulerWrap.offsetWidth; //容器宽度
    var division = winWidth / 12; //每个刻度的距离 分割线
    //刻度值数组
    var scaleValueList = [];
    for (var i = 0; i <= initParams.maxScale; i += 5) {
      scaleValueList.push(i);
    }
    var canvas = rulerWrap.getElementsByTagName("canvas")[0]; //获取容器下的canvas标签
    //没有canvas就创建一个
    if (!canvas) {
      canvas = document.createElement("canvas"); //创建canvas标签
      canvas.width = winWidth;
      canvas.height = initParams.height;
      rulerWrap.appendChild(canvas);
    }
    var cxt = canvas.getContext("2d");

    if (window.devicePixelRatio) {
      canvas.width = window.devicePixelRatio * winWidth;
      canvas.height = window.devicePixelRatio * initParams.height;
      cxt.scale(window.devicePixelRatio, window.devicePixelRatio);
    }

    //画刻度尺
    function drawRuler(count) {
      count = count - 6;

      //清空画布
      cxt.clearRect(0, 0, winWidth, initParams.height);

      //刻度尺背景
      if (initParams.background) {
        cxt.fillStyle = initParams.background;
        cxt.fillRect(0, 0, canvas.width, initParams.height);
      }
 
      //画刻度线
      for (var i = initParams.startI; i < initParams.maxScale + 1; i++) {
        cxt.beginPath();
        cxt.save();
        cxt.strokeStyle = initParams.color ? initParams.color : "#bbb";
        cxt.lineWidth = 1;
        cxt.lineCap = "round";
        cxt.moveTo(division * i - count * division, 40); // 第二个参数为开始的y轴坐标
        cxt.lineTo(
          division * i - count * division,
          Math.floor(initParams.height * 0.7)
        );
        if (i % 5 === 0) {
          cxt.strokeStyle = initParams.color ? initParams.color : "#666";
          cxt.lineTo(
            division * i - count * division,
            Math.floor(initParams.height * 0.52)
          );
        }
        cxt.moveTo(division * i - count * division, 40);
        cxt.lineTo(150, 40);
        cxt.stroke();
        cxt.restore();
        cxt.closePath();
      }

      // 从哪个开始渲染数字
      let index = scaleValueList.findIndex((item, index) => {
        return item > initParams.startI;
      });
      //添加体重数字
      cxt.beginPath();
      cxt.font = "14px Arial";
      cxt.fillStyle = initParams.color ? initParams.color : "#333";
      cxt.textAlign = "center";
      cxt.textBaseline = "middle";
      for (var i = index; i < scaleValueList.length; i++) {
        cxt.fillText(
          scaleValueList[i].toString()+'岁',
          division * i * 5 - count * division,
          Math.floor(initParams.height * 0.3)
        );
      }

      cxt.closePath();

      //中心刻度线
      cxt.beginPath();
      cxt.save();
      cxt.strokeStyle = initParams.markColor;
      cxt.lineWidth = 1;
      cxt.lineCap = "round";
      cxt.moveTo(winWidth / 2, 0);
      cxt.lineTo(winWidth / 2, Math.floor(initParams.height * 0.7));
      cxt.stroke();
      cxt.restore();
      cxt.closePath();

      //  中心刻度线下三角形
      cxt.beginPath();
      cxt.moveTo(winWidth / 2 + 7, 40);
      cxt.lineTo(winWidth / 2 - 7, 40);
      cxt.lineTo(winWidth / 2, 30);
      cxt.fillStyle = "#F54C22";
      cxt.closePath();
      cxt.fill();
    }

    if (window.devicePixelRatio) {
      canvas.style.transform = "scale(" + 1 / window.devicePixelRatio + ")";
      canvas.style.transformOrigin = "left top";
    }

    drawRuler(count);

    //滑动相关
    var initX = 0, //初始x 距离
      endX = 0, //结束x 距离
      distanceX = 0, //移动距离
      _distanceX = 0, // 判断用的移动距离
      lastX = count; //上次移动距离

    if (!canvas) return false;

    //手指按下
    canvas.addEventListener(
      "touchstart",
      function (e) {
        initX = e.targetTouches[0].pageX;
      },
      false
    );
    //手指滑动
    canvas.addEventListener(
      "touchmove",
      function (e) {
        endX = e.targetTouches[0].pageX;
        console.log(endX, "endX");
        moveEvent();
      },
      false
    );

    //手指抬起
    canvas.addEventListener(
      "touchend",
      function (e) {
        lastX = count;
        overEvent();
      },
      false
    );

    var isMouseDown = false; //鼠标是否按下

    //鼠标按下
    canvas.addEventListener(
      "mousedown",
      function (e) {
        isMouseDown = true;
        initX = e.layerX;
      },
      false
    );
    //鼠标移动
    canvas.addEventListener(
      "mousemove",
      function (e) {
        if (!isMouseDown) {
          return false;
        }
        endX = e.layerX;
        moveEvent();
      },
      false
    );

    //鼠标抬起&离开
    canvas.addEventListener(
      "mouseup",
      function (e) {
        lastX = count;
        isMouseDown = false;
        overEvent();
      },
      false
    );

    canvas.addEventListener(
      "mouseleave",
      function (e) {
        if (isMouseDown) {
          lastX = count;
          isMouseDown = false;
          overEvent();
        }
      },
      false
    );

    //手指&鼠标移动事件
    function moveEvent() {
      distanceX = Math.floor((initX-endX) / (winWidth / 12));
      if (distanceX === _distanceX) {
        return false;
      }
      _distanceX = distanceX;
      count = lastX + distanceX;

      if (count >= initParams.maxScale || count <= 0) {
        count = initParams.maxScale ;
      } else if(count <minSildeNum) {
        count = minSildeNum
      }
      drawRuler(count);

      if (initParams.isConstant) {
        params.success && params.success(count);
      }
    }

    //手指&鼠标结束事件
    function overEvent() {
      if (count > maxSildeNum) {
        lastX = count = count > maxSildeNum ? maxSildeNum : count;
      } else if (count < minSildeNum) {
        lastX = count = count < minSildeNum ? minSildeNum : count;
      } 
      drawRuler(count);

      //返回最后的值
      params.success && params.success(count);
    }
  },
};

接下来,在vue中引入,然后使用

<script setup>
import { ref, onMounted } from "vue";
import { ruler } from "../assets/ruler";
onMounted(() => {
  init();
});
const btn =()=>{
    let value = ref(20)
    console.log(value);
    //调用刻度尺方法
  ruler.initPlugin({
    el: "ruler3", //容器id
    height: 50, //刻度尺高度
    maxScale: 300, //最大刻度
    startValue: value.value, //刻度开始的初始值
    region: [0, 220], //选择刻度的区间范围
    background: "#ffffff", //刻度尺背景色
    color: "#000000", //刻度线和字体的颜色
    markColor: "#3786db", //中心刻度标记颜色
    isConstant: true, //是否不断地获取值
    minScale:36,
    success: function (res) {
      //   console.log(res);
      rulerText3.value = res;
    },
  });
}
const init = () => {
  var rulerText3 = document.getElementById("rulerText3");
  rulerText3.value = 200;
  //调用刻度尺方法
  ruler.initPlugin({
    el: "ruler3", //容器id
    height: 50, //刻度尺高度
    maxScale: 300, //最大刻度
    startValue: 200, //刻度开始的初始值
    region: [0, 220], //选择刻度的区间范围
    background: "#ffffff", //刻度尺背景色
    color: "#000000", //刻度线和字体的颜色
    markColor: "#3786db", //中心刻度标记颜色
    isConstant: true, //是否不断地获取值
    minScale:36,
    success: function (res) {
      //   console.log(res);
      rulerText3.value = res;
    },
  });
};
</script>
<template>

  <input id="rulerText3" class="text-input" type="text" value="" />
  <button id="button" @click="btn">按钮</button>
  <!-- 刻度尺容器(必要的) -->
  <div class="ruler-wrap" id="ruler3"></div>
</template>
<style lang="scss" scoped>
.ruler-wrap {
  width: 100%;
  max-width: 600px;
  /*height: 60px;*/
  line-height: 1px;
  overflow: hidden;
  margin: 0 auto 50px;
}
#ruler3 {
  width: 300px;
  height: 200px;
  border: 1px solid red;
}
.text-input {
  display: block;
  width: 100px;
  height: 30px;
  border-radius: 5px;
  background: #f6f6f6;
  border: none;
  text-align: center;
  font-size: 14px;
  color: #4142cc;
  font-weight: bold;
  letter-spacing: 1px;
  margin: 0 auto;
}
.text-input:focus {
  outline: none;
}
</style>

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值