最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • canvas之旅系列----(五)

    正文概述 掘金(不想做后端的前端不是好运维)   2021-01-12   522

    canvas绘制水球图

    canvas之旅系列----(五)

    分析准备

    分析整个水球图,波形的绘制就是整个绘制过程的最大的难点。绘制波形,第一个难点就是波纹的形状,其实可以选择两种方案绘制,第一种,采取圆弧拼接的形式;第二种就是采用三次贝塞尔曲线来绘制曲线。为了再次熟悉三次贝塞尔曲线的绘制过程,所以采用了方式二。波形的绘制难点二就是如何使得波形绘制在圆内,此处便要引入clipsaverestore三个函数的使用了,其详细情况可见MDN文档。

    绘制水球图的第二个难点,就是如何绘制水漫文字的效果。水漫文字的效果我们观察发现,未被水漫部分则为最上层颜色,否则为白色。所以,我们就可以考虑先绘制一个带底色的文字,之后再利用裁剪效果,来绘制被水漫的白色部分。

    • 先绘制一个带底色的文字

    canvas之旅系列----(五)

    • clip裁剪后在相同位置绘制一个相同的白色文字

    canvas之旅系列----(五)

    我们总共绘制了三层水波纹,在每层绘制水波纹的时候都需要绘制白色部分,否则后面的谁的波纹会将文字盖住。但是带底色的文字只需要在最下层波纹绘制的时候绘制即可。

    最后,在水球图绘制完成后,我们会发现圆圈外侧并不光滑,成锯齿状,此时,我们则需要使用canvas的抗锯齿技巧,其实抗锯齿很简单,就像大家在在凑很近看墙面时候,你可能发现墙面是坑坑洼洼的,但是站的远,就可能觉得墙面很平整。因为站的远就看不清细节,我们脑子机自动的认为墙面平整了,抗锯齿也可以利用一样的原理,只要看不清真实边缘,那么边缘则看起来就比较平滑了。所以要用到阴影来模糊掉边缘即可,需要使用到shadowColor shadowBlur shadowOffsetX shadowOffsetY这几个属性。

    代码示例

    function WaterCahrt(id, data) {
      let canvas = document.getElementById(id)
      let ctx = canvas.getContext('2d')
      let canvasWidth = canvas.width > canvas.height ? canvas.height : canvas.width
      let r = canvasWidth * 0.8 / 2
      let offset = [0, 20, 40]
      this.canvas = canvas
      this.ctx = ctx
      this.data = data
      this.r = r // 圆半径
      this.center = canvasWidth / 2 //圆心x(y)
      this.intervalId = null
      Object.defineProperty(this, 'offset', { // 定义水波图的偏移量,当偏移量发生变化时自动触发更新
        enumerable: false,
        configurable: false,
        get() {
          return offset
        },
        set(val) {
          offset = val
          this.refresh()
        }
      })
    }
    

    此处offset设置成了个数组,是为了使三个水波的移动速度具有一定差距。

    /**
     * 绘制水波图
     * @param {number} basex 波纹的起始x值
     * @param {number} basey 波纹的起始点y值
     * @param {strign} color 波纹颜色
     * @param {boolean} flag 是否绘制与波纹相同颜色的文字,理论上只需要最下层的波纹才需要绘制
     */
    WaterCahrt.prototype.drawWater = function(basex, basey, color, flag) {
      let bezier = this.getBezierPoints(basex, basey) // 生成三次贝塞尔曲线
      this.ctx.save() // 存储画笔状态
      // 绘制波形
      this.ctx.beginPath()
      this.ctx.moveTo(this.center - this.r, this.center + this.r)
      this.ctx.lineTo(bezier.x, bezier.y)
      bezier.points.forEach((item) => {
        this.ctx.bezierCurveTo(item.cp1x, item.cp1y, item.cp2x, item.cp2y, item.x, item.y)
      })
      this.ctx.lineTo(this.center + this.r, this.center + this.r)
      this.ctx.closePath()
      this.ctx.fillStyle = color
      this.ctx.shadowColor = color //抗锯齿
      this.ctx.shadowBlur = 2
      this.ctx.fill()
      this.ctx.shadowBlur = 0
      //绘制带底色文字
      this.ctx.font = `normal ${this.r * 0.2}px blod`
      this.ctx.textAlign = "center"
      if(flag)
        this.ctx.fillText(`${(this.data * 100).toFixed(1)}%`, this.center, this.center)
      // 绘制文字白色部分
      this.ctx.clip() // 按照所绘路径裁剪
      this.ctx.fillStyle = '#ffffff'
      this.ctx.fillText(`${(this.data * 100).toFixed(1)}%`, this.center, this.center)
      this.ctx.restore() // 恢复画笔状态,即到未裁剪之前状态
      return this
    }
    

    三次贝塞尔曲线的点的生成不在赘述,详细生成原理可参考文章《贝塞尔曲线控制点确定的方法》。

    总结

    此次水球图的绘制,主要是为了对clip、save、restore相关的方法的尝试,同时还引入了抗锯齿的一个小技巧。整体绘制上计算量相对并不大,且无交互效果,只是存在一个动画效果,动画效果的实现则是使用setInterval间隔绘制动画帧即可。整体上来说并没有太大的难度。


    下载网 » canvas之旅系列----(五)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元