canvas 画一条波浪线 进度条

前言: 记得刚接触Web的时候, 老板需要画一个有波浪线的进度球; 那个时候无赖不熟悉canvas; 所以这个功能没有满足; 今天刚好有时间来满足下心愿

第一步 我们先实现一个波浪

 这里核心就用到了一个 二维的 贝塞尔曲线: quadraticCurveTo

drawWave() {
  
  this.ctx.beginPath()
  //线条起点
  this.ctx.moveTo(0, this.canvasCenter.y); //宽高
  this.ctx.setStrokeStyle("#002ae6") //颜色
  this.ctx.setLineWidth(1)
  for (let i = 0; i < this.step * 2; i++) {
   
    if (i % 2 == 0) {
      this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2, this.canvasCenter.y + this
        .stepWaveHeight, this.stepWave * (i + 1), this.canvasCenter.y)
    } else {
      this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2, this.canvasCenter.y - this
        .stepWaveHeight, this.stepWave * (i + 1), this.canvasCenter.y)
    }
  }
  //右下角的点
  this.ctx.lineTo(this.canvasWidth, this.canvasHeight)
  //左下角的点
  this.ctx.lineTo(0, this.canvasHeight)
  //闭合点
  this.ctx.closePath()
  //渐变色
  let grad = this.ctx.createLinearGradient(0, 0, 0, this.canvasHeight);
  grad.addColorStop(0, '#1e92ea')
  grad.addColorStop(1, '#2C405A')
  // this.ctx.setFillStyle('#3cee06')
  this.ctx.setFillStyle(grad)

  this.ctx.fill()
  this.ctx.stroke()
  this.ctx.draw()
},

完整的脚本:

<template>
  <view class="canvas-view">
    <canvas :style="{'width': width + 'rpx','height': height  + 'rpx','backgroundColor': '#d2d8d2'}"
      canvas-id="firstCanvas" id="firstCanvas"></canvas>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        ctx: null,
        width: 600,
        height: 400,
        step: 2.5,
        stepHeight: -20,
      }
    },
    mounted() {
      this.ctx = uni.createCanvasContext('firstCanvas', this)
      //this.drawWave()
      this.drawWave()
    },

    computed: {
      canvasWidth() {
        return uni.upx2px(this.width)
      },
      canvasHeight() {
        return uni.upx2px(this.height)
      },
      stepWave() {
        return uni.upx2px(this.canvasWidth) / this.step
      },
      stepWaveHeight() {
        return uni.upx2px(this.stepHeight)
      },
      canvasCenter() {
        return {
          x: this.canvasWidth / 2,
          y: this.canvasHeight / 2
        }
      }
    },
    methods: {
      drawWave() {
        this.ctx.beginPath()
        //线条起点
        this.ctx.moveTo(0, this.canvasCenter.y); //宽高
        this.ctx.setStrokeStyle("#002ae6") //颜色
        this.ctx.setLineWidth(1)   
        for (let i = 0; i < this.step * 2; i++) {
          if (i % 2 == 0) {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2, this.canvasCenter.y + this
              .stepWaveHeight, this.stepWave * (i + 1), this.canvasCenter.y)
          } else {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2, this.canvasCenter.y - this
              .stepWaveHeight, this.stepWave * (i + 1), this.canvasCenter.y)
          }
        }

        this.ctx.lineTo(this.canvasWidth, this.canvasHeight)
        this.ctx.lineTo(0, this.canvasHeight)
        this.ctx.closePath()

        let grad = this.ctx.createLinearGradient(0, 0, 0, this.canvasHeight);
        grad.addColorStop(0, '#1e92ea')
        grad.addColorStop(1, '#2C405A')
        // this.ctx.setFillStyle('#3cee06')
        this.ctx.setFillStyle(grad)

        this.ctx.fill()
        this.ctx.stroke()
        this.ctx.draw()
      },
    }
  }
</script>

<style lang="scss" scoped>
  .canvas-view {}
</style>

引入我们的脚本

<template>
  <view class="content">
    <canvas-view></canvas-view>
  </view>
</template>

第二步 我们让波浪 ()动起来 (花式玩法

 

扫描二维码关注公众号,回复: 14371235 查看本文章

动起来的核心就是: 本身波浪变长一些,刚开始的时候,开始位置 是一个负的值,随着时间 叠加;然后在一个波浪 周期位置 复位一下就好了

 

后面还有几个 花式玩法: 也就是动态改变波浪 高度这些值有兴趣的还可以改变下波浪的长度

//计算位移 波浪高度的值
moveWave() {
  let offset = -this.stepWave * 2
  setInterval(() => {
    offset++
    if (offset >= 0) {
      offset = -this.stepWave * 2
    }

    if (this.stepHeight > -10) {
      this.trigger = true
    }
    if (this.stepHeight < -50) {
      this.trigger = false
    }
    if (this.trigger) {
      this.stepHeight -= 0.2
    } else {
      this.stepHeight += 0.2
    }

    this.drawWave(offset)
  }, 10)
},

完整脚本:

<template>
  <view class="canvas-view">
    <canvas :style="{'width': width + 'rpx','height': height  + 'rpx','backgroundColor': '#d2d8d2'}"
      canvas-id="firstCanvas" id="firstCanvas"></canvas>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        ctx: null,
        width: 600,
        height: 400,
        step: 2,
        stepHeight: -60,
        trigger: true
      }
    },
    mounted() {
      this.ctx = uni.createCanvasContext('firstCanvas', this)
      //this.drawWave()
      //this.drawWave()
      this.moveWave()
    },

    computed: {
      canvasWidth() {
        return uni.upx2px(this.width)
      },
      canvasHeight() {
        return uni.upx2px(this.height)
      },
      stepWave() {
        return uni.upx2px(this.canvasWidth) / this.step
      },
      stepWaveHeight() {
        return uni.upx2px(this.stepHeight)
      },
      canvasCenter() {
        return {
          x: this.canvasWidth / 2,
          y: this.canvasHeight / 2
        }
      }
    },
    methods: {
      //计算位移 波浪高度的值
      moveWave() {
        let offset = -this.stepWave * 2
        setInterval(() => {
          offset++
          if (offset >= 0) {
            offset = -this.stepWave * 2
          }

          if (this.stepHeight > -10) {
            this.trigger = true
          }
          if (this.stepHeight < -50) {
            this.trigger = false
          }
          if (this.trigger) {
            this.stepHeight -= 0.2
          } else {
            this.stepHeight += 0.2
          }

          this.drawWave(offset)
        }, 10)
      },
      drawWave(offset) {
        this.ctx.beginPath()
        //线条起点
        this.ctx.moveTo(0 + offset, this.canvasCenter.y); //宽高
        this.ctx.setStrokeStyle("#002ae6") //颜色
        this.ctx.setLineWidth(1)
        for (let i = 0; i < this.step * 3; i++) {
          if (i % 2 == 0) {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y + this
              .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
          } else {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y - this
              .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
          }
        }

        this.ctx.lineTo(this.stepWave * (this.step * 2 + 3) + offset, this.canvasHeight)
        this.ctx.lineTo(0 + offset, this.canvasHeight)
        this.ctx.closePath()

        let grad = this.ctx.createLinearGradient(0, 0, 0, this.canvasHeight);
        grad.addColorStop(0, '#1e92ea')
        grad.addColorStop(1, '#2C405A')
        // this.ctx.setFillStyle('#3cee06')
        this.ctx.setFillStyle(grad)

        this.ctx.fill()
        this.ctx.stroke()
        this.ctx.draw()
      },
    }
  }
</script>

<style lang="scss" scoped>
  .canvas-view {}
</style>

第三步 我们给波浪 加个遮罩

 drawWave(offset) 整理

drawWave(offset) {

  // 遮罩开始
  this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
  this.ctx.save();
  this.ctx.beginPath();

  this.ctx.fillStyle = '#d5ffc5'
  this.ctx.arc(this.canvasCenter.x, this.canvasCenter.y, 100, 0, Math.PI * 2, false);
  this.ctx.closePath();
  this.ctx.fill();
  // this.ctx.setStrokeStyle("#d5ffc5")
  // this.ctx.stroke();
  this.ctx.clip();
  //this.ctx.restore()
  // 遮罩结束


  this.ctx.beginPath()
  //线条起点
  this.ctx.moveTo(0 + offset, this.canvasCenter.y); //宽高
  // this.ctx.setStrokeStyle("#002ae6") //颜色
  this.ctx.setLineWidth(1)
  for (let i = 0; i < this.step * 3; i++) {
    if (i % 2 == 0) {
      this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y + this
        .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
    } else {
      this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y - this
        .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
    }
  }

  this.ctx.lineTo(this.stepWave * (this.step * 2 + 3) + offset, this.canvasHeight)
  this.ctx.lineTo(0 + offset, this.canvasHeight)
  this.ctx.closePath()

  let grad = this.ctx.createLinearGradient(0, 0, 0, this.canvasHeight);
  grad.addColorStop(0, '#1e92ea')
  grad.addColorStop(1, '#2C405A')

  // this.ctx.setFillStyle('#3cee06')
  this.ctx.setFillStyle(grad)

  this.ctx.fill()
  this.ctx.restore();
  //this.ctx.strokeStyle = "red"
  //this.ctx.stroke()


  this.ctx.draw()
},

 完整脚本:

<template>
  <view class="canvas-view">
    <canvas :style="{'width': width + 'rpx','height': height  + 'rpx','backgroundColor': '#d2d8d2'}"
      canvas-id="firstCanvas" id="firstCanvas"></canvas>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        ctx: null,
        width: 600,
        height: 400,
        step: 2,
        stepHeight: -60,
        trigger: true
      }
    },
    mounted() {
      this.ctx = uni.createCanvasContext('firstCanvas', this)
      //this.drawWave()
      //this.drawWave()
      this.moveWave()
    },

    computed: {
      canvasWidth() {
        return uni.upx2px(this.width)
      },
      canvasHeight() {
        return uni.upx2px(this.height)
      },
      stepWave() {
        return uni.upx2px(this.canvasWidth) / this.step
      },
      stepWaveHeight() {
        return uni.upx2px(this.stepHeight)
      },
      canvasCenter() {
        return {
          x: this.canvasWidth / 2,
          y: this.canvasHeight / 2
        }
      }
    },
    methods: {
      //计算位移 波浪高度的值
      moveWave() {
        let offset = -this.stepWave * 2
        setInterval(() => {
          offset++
          if (offset >= 0) {
            offset = -this.stepWave * 2
          }

          if (this.stepHeight > -10) {
            this.trigger = true
          }
          if (this.stepHeight < -50) {
            this.trigger = false
          }
          if (this.trigger) {
            this.stepHeight -= 0.2
          } else {
            this.stepHeight += 0.2
          }

          this.drawWave(offset)
        }, 10)
      },
      drawWave(offset) {

        // 遮罩开始
        this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
        this.ctx.save();
        this.ctx.beginPath();

        this.ctx.fillStyle = '#d5ffc5'
        this.ctx.arc(this.canvasCenter.x, this.canvasCenter.y, 100, 0, Math.PI * 2, false);
        this.ctx.closePath();
        this.ctx.fill();
        // this.ctx.setStrokeStyle("#d5ffc5")
        // this.ctx.stroke();
        this.ctx.clip();
        //this.ctx.restore()
        // 遮罩结束


        this.ctx.beginPath()
        //线条起点
        this.ctx.moveTo(0 + offset, this.canvasCenter.y); //宽高
        // this.ctx.setStrokeStyle("#002ae6") //颜色
        this.ctx.setLineWidth(1)
        for (let i = 0; i < this.step * 3; i++) {
          if (i % 2 == 0) {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y + this
              .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
          } else {
            this.ctx.quadraticCurveTo(this.stepWave * (i) + this.stepWave / 2 + offset, this.canvasCenter.y - this
              .stepWaveHeight, this.stepWave * (i + 1) + offset, this.canvasCenter.y)
          }
        }

        this.ctx.lineTo(this.stepWave * (this.step * 2 + 3) + offset, this.canvasHeight)
        this.ctx.lineTo(0 + offset, this.canvasHeight)
        this.ctx.closePath()

        let grad = this.ctx.createLinearGradient(0, 0, 0, this.canvasHeight);
        grad.addColorStop(0, '#1e92ea')
        grad.addColorStop(1, '#2C405A')

        // this.ctx.setFillStyle('#3cee06')
        this.ctx.setFillStyle(grad)

        this.ctx.fill()
        this.ctx.restore();
        //this.ctx.strokeStyle = "red"
        //this.ctx.stroke()


        this.ctx.draw()
      },
    }
  }
</script>

<style lang="scss" scoped>
  .canvas-view {}
</style>

猜你喜欢

转载自blog.csdn.net/nicepainkiller/article/details/125716354