美文网首页
小程序 canvas自定义画进度条(可点击&滑动)——简约版

小程序 canvas自定义画进度条(可点击&滑动)——简约版

作者: hao_developer | 来源:发表于2023-03-29 19:54 被阅读0次

    效果图


    image.png
    image.png
    image.png

    知识点一

    定义和用法

    atan2() 返回从原点(0,0) 到 (x,y) 点的线段与 x 轴正方向之间的平面角度(弧度值),也就是 Math.atan2(y,x)。(返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。)

    注意: atan2()有两个参数, y 坐标是作为第一个参数传递, x 坐标作为第二个参数传递。

    语法
    Math.atan2(y,x)
    
    参数 描述
    y 必须。一个数字代表Y坐标
    x 必须。 一个数字代表x坐标
    返回值
    类型 描述
    Number x 的反正切值。返回一个 -PI 到 PI 之间的数值。表示点 (x, y) 对应的偏移角度。这是一个逆时针角度,以弧度为单位,正X轴和点 (x, y) 与原点连线 之间。注意此函数接受的参数:先传递 y 坐标,然后是 x 坐标。

    知识点二

    弧度 = 角度 * Math.PI / 180

    角度 = 弧度 * 180 / Math.PI

    弧度制与角度制的换算公式:1度=π/180≈0.01745弧度1弧度=180/π≈57.3度。角的度量单位通常有两种,一种是角度制,另一种就是弧度制。

    1弧度=180/pai 度。

    1度=pai/180 弧度。

    记不住的时候就像圆。

    一个圆是360度,2pai弧度。

    image.png

    弧度制的基本思想是使圆半径与圆周长有同一度量单位,然后用对应的弧长与圆半径之比来度量角度,这一思想的雏型起源于印度。

    那么半圆的弧长为π,此时的正弦值为0,就记为sinπ= 0,同理,1/4圆周的弧长为π/2,此时的正弦为1,记为sin(π/2)=1。从而确立了用π、π/2分别表示半圆及1/4圆弧所对的中心角。其它的角也可依此类推。

    知识点三

    image.png

    wxml文件

    <view style="width:100vw;height:50vh;margin-top: 200rpx;" class="flex_column flex_center">
      <canvas bindtouchmove="doTouchMove" bindtouchstart="doTouchStart" canvas-id="circle" style="width:70vw;height:70vw;border: 1rpx solid red;"></canvas>
    </view>
    <view style="text-align: center;color: white;margin-top: 50rpx;font-size: 40rpx;">
      {{realValue}} min
    </view>
    

    wxss文件

    page{
      background: #00a8ff;
    }
    
    .text_hint{ 
      font-size:80%;
      font-family:PingFang SC;
      font-weight:500;
      color:rgba(204,204,204,1);
    }
    
    .text_name{ 
      margin-top: 5px;
      font-size:100%;
      font-family:PingFang SC;
      font-weight:500;
      color:rgba(0,0,0,1);
    }
    
    .flex_column{
     display: flex;
     flex-direction: column; 
    }
    
    .flex_center{
      justify-content: center;
      align-items: center
    }
    

    js文件

    const app = getApp()
    var lasttime = 0; //上次滑动时间
    
    Page({
      data: {
        maxTemp: 100, //最大值
        value: 0, //弧度数
        realValue: 0, //弧度数对应的分钟
      },
      onLoad() {
        this.drawCircle();
      },
      onShow() {
    
      },
      doTouchStart: function (res) {
        this.doTouchMove(res);
      },
      doTouchMove: function (res) {
        let nowtime = (new Date()).getTime();
        //100ms触发一次 减少不必要的绘图
        if (nowtime - lasttime < 100) {
          return;
        }
        lasttime = nowtime;
        let x = res.touches[0].x; //触摸点的x轴坐标
        let y = res.touches[0].y; //触摸点的y轴坐标
        console.log("触摸点", x, y);
        let width = app.globalData.width * 0.7;
        let height = app.globalData.width * 0.7;
    
        //获取中心坐标
        let centerPoint = {
          x: width / 2,
          y: height / 2
        }
        console.log("中心坐标", centerPoint);
        let line = 30; //圆环的宽度
        const radius = width / 2 * 0.8; //圆环的半径
        //最大圆的距离
        let maxDistance = radius + line / 2;
        //最小圆的距离
        let minDistance = radius - line / 2;
        //计算到圆心的距离(触摸点到圆心的距离)
        let distance = Math.sqrt(Math.pow(centerPoint.x - x, 2) + Math.pow(centerPoint.y - y, 2));
        console.log('最大:%s  最小:%s  当前:%s', maxDistance, minDistance, distance);
        //触摸点再刻度上
        if (distance <= maxDistance && distance >= minDistance) {
          //atan2() 返回从原点(0,0) 到 (x,y) 点的线段与 x 轴正方向之间的平面角度(弧度值),也就是 Math.atan2(y,x)
          //弧度 = 角度 * Math.PI / 180
          //角度 = 弧度 * 180 / Math.PI 
          let value = Math.atan2(y - centerPoint.y, x - centerPoint.x); //计算触摸点到centerPoint点的弧度
          this.data.value = value;
          //分成两份,0~Math.PI 和 0~ -Math.PI
          //this.data.maxTemp / 2 最大值的一半
          //Math.PI / (this.data.maxTemp / 2))  Math.PI每份占多少
          if(value >= 0 && this.data.value <= Math.PI){
            this.setData({
              realValue: Math.ceil(value / (Math.PI / (this.data.maxTemp / 2))),
            });
          }else{
            this.setData({
              realValue: 50 + Math.ceil((Math.PI - Math.abs(value)) / (Math.PI / (this.data.maxTemp / 2))),
            });
          }
          this.drawCircle();
        }
      },
      drawCircle() {
        //定义画图大小    
        let width = app.globalData.width * 0.7; //canvas宽
        let height = app.globalData.width * 0.7; //canvas高
    
        //获取中心坐标
        let centerPoint = {
          x: width / 2,
          y: height / 2
        }
        const ringWidth = 30; //圆环宽度
        const radius = width / 2 * 0.8;
        let ctx = wx.createCanvasContext('circle');
        ctx.save();
        ctx.translate(centerPoint.x, centerPoint.y); //画布移动到中心
    
        //画背景圆环
        ctx.beginPath();
        ctx.setStrokeStyle('pink');
        ctx.setLineWidth(ringWidth);
        ctx.arc(0, 0, radius, 0, 2 * Math.PI);
        ctx.stroke();
    
        //画进度弧弧
        ctx.beginPath();
        ctx.setStrokeStyle('red');
        ctx.setLineCap('round');
        ctx.setLineWidth(ringWidth);
        ctx.arc(0, 0, radius, 0, this.data.value);
        ctx.stroke();
    
        ctx.draw();
      }
    })
    

    相关文章

      网友评论

          本文标题:小程序 canvas自定义画进度条(可点击&滑动)——简约版

          本文链接:https://www.haomeiwen.com/subject/qnofddtx.html