美文网首页Web 前端
修改 zrender 的图形填充方式

修改 zrender 的图形填充方式

作者: 时光觅迹 | 来源:发表于2021-01-07 15:53 被阅读0次

    H5 的 canvas 绘制图形,在填充图形时,支持两种填充方式:非零环绕填充(默认)、奇偶填充。

    而 zrender 没有对我们提供选择填充方式的接口,直接使用了默认填充方式,这样在某些情况下,我们绘制出来的图形可能就会不是我们想要的结果。

    例如(此处例图为假设,模拟可能发生的情况):


    我们想要的 实际得到的

    可以看出,我们想要的是在大的图形内区域内去除两个小的区域,但是实际上只有一块区域被去除了,另一块区域仍然被填充,这就是「非零环绕填充」带来的结果。

    想要解决这个问题,只有使用「奇偶填充」,可是 zrender 没有给我们提供接口,那么我们就只有修改它的源码了……

    源码获取方式自行解决,可以通过 gitnpm 或其他方式都可以,这里以 npm 方式举例。

    我们可以通过 npmzrender 下载到本地,然后在 node_modules 中找到 zrender 目录,然后修改 src 目录以下文件:

    1. /graphic/Style.js:
      Style.prototype 中,增加:
    /**
     * 'nonzero': 非零环绕规则,默认值
     * 'evenodd': 奇偶环绕规则
     */
    fillType: 'nonzero'
    
    1. /graphic/Path.js:
      Path.prototype 中,在下面代码内:
    if (hasFill) {
      ...
    }
    

    修改两处 path.fill(ctx);path.fill(ctx, style);

    3:/core/PathProxy.js
    PathProxy.prototype 中,

    fill: function (ctx) {
      ctx && ctx.fill();
      this.toStatic();
    },
    

    改为

    fill: function (ctx, style) {
      ctx && ctx.fill(style.fillType);
      this.toStatic();
    },
    

    最后,重新编译 zrender ,在 dist 目录中就是编译后的新文件。

    怎么使用

    在使用的时候,我们使用 zrender 创建图形时,继承 zrenderPath ,在 style 属性中,设置 fillType: xxx 就行了:

    
    /** 自定义封闭形状 */
    export var CustomizeRegions = zrender.Path.extend({
      type: 'Regions',
      shape: {
        offset: 0,
        coordinates: {
          inverted: false,
          regions: []
        }
      },
      style: {
        stroke: '#000',
        fill: 'rgba(0, 0, 255, 0.2)',
        // 设置填充方式为 「奇偶填充」
        fillType: 'evenodd'
      },
      buildPath: function (ctx, shape) {
        // console.warn(ctx)
    
        // ctx.beginPath();
        // 旋转算法 >>>
        // if (shape.coordinates.inverted) {
        //   ctx.moveTo(rect1[0], rect1[1] + offset)
        //   ctx.lineTo(rect1[0], rect2[1] + offset)
        //   ctx.lineTo(rect2[0], rect2[1] + offset)
        //   ctx.lineTo(rect2[0], rect1[1] + offset)
        //   ctx.closePath()
        // }
    
        shape.coordinates.regions.forEach(function (region, i) {
        // console.info("region.length = ", region.length);
          if (region.length <= 0) {
            return
          }
          ctx.moveTo((region[0][0]), (region[0][1]) + shape.offset)
          for (let i = 1; i < region.length; i++) {
            ctx.lineTo((region[i][0]), (region[i][1]) + shape.offset)
          }
          ctx.closePath()
        })
      }
    })
    

    相关文章

      网友评论

        本文标题:修改 zrender 的图形填充方式

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