图片标注编辑平台搭建系列教程(5)——线宽不居中问题

背景

fabric中的polyline和polygon(继承自polyline),有一个普遍问题,就是如果设置了left和top后,同时设置了线宽,会发现线宽并不是沿着坐标序列居中渲染,而是以坐标最小外接矩形的左上角为原点,整体往右和下渲染。本期从源码内容详细分析成因。

现象

fabric中有一个选中框的概念,有几个控制的锚点,途中的矩形是500px,同时线宽20,从右下角绿色点(500,500)的位置可以看出,这个选中框的宽度=500+20=520,即width+strokeWidth。

如果画一条(0,0)到(500,500)的线,在不添加left和top的情况下,如左图,可以看到线的中心线是符合要求的。但如果你添加了left=0,top=0,那么渲染效果如右图。可以看出,线的端点有一定的偏移,具体来看,整体偏移了strokeWidth/2。

如果是(0,0)到(0,500)的线,在不设置left和top的效果如左图,设置left=0,top=0是,效果如右图。

原因

造成上述的原因是:在polyline的初始化方法中,调用了_setPositionDimensions方法,该方法中对于left和top没有赋值的情况,源代码自身进行了赋值(calcDim.left - strokeWidth / 2);一旦你设置了left和top,就会采用你设置的left和top,从而导致渲染上的偏移。(注意,这里的偏移程度取决于strokeWidth,对于线而言,strokeWidth的设置不可避免,因此只要设置了left和top多少都会有一定的偏移)。

由于每个object的ctx原点是基于ctx transform后,再一次进行偏移到object中心点,其偏移量为:

javascript 复制代码
x = this.left + 0.5 * (width + strokeWidth) = calcDim.left + 0.5 * width
y = this.top + 0.5 * (height + strokeWidth) = calcDim.top + 0.5 * height

在this.left 赋值的情况下,偏移量为:

javascript 复制代码
x = this.left + 0.5 * (width + strokeWidth) = calcDim.left + 0.5 * (width + strokeWidth);
y = this.top + 0.5 * (height + strokeWidth) = calcDim.top + 0.5 * (height + strokeWidth);

而绘制时每个点的坐标的偏移量this.pathOffset始终等于

javascript 复制代码
{
    x: calcDim.left + width / 2,
    y: calcDim.top + height / 2
}

因此,最终后者的坐标整体会比前者往x、y正方向偏移0.5 * strokeWidth。

而由于_setPositionDimensions只在canvas.add(object)时才调用,因此,在后续缩放整个画布的过程中,this.left、this.top的值始终是定值,但是strokeWidth为了维持缩放后的绝对像素宽度,始终在动态变化,此时,ctx的偏移量x、y在变化,而pathOffset没有变,最终相对于图片的位置还是在变化。

解决方案

为了解决这个问题,需要在子类覆写的_render方法内,写以下代码:

确保偏移量x、y计算正确。

预告

下一章简单讲讲fabric的渲染原理。

相关推荐
请叫我欧皇i18 分钟前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript
533_21 分钟前
[vue] 深拷贝 lodash cloneDeep
前端·javascript·vue.js
guokanglun27 分钟前
空间数据存储格式GeoJSON
前端
zhang-zan1 小时前
nodejs操作selenium-webdriver
前端·javascript·selenium
猫爪笔记1 小时前
前端:HTML (学习笔记)【2】
前端·笔记·学习·html
brief of gali1 小时前
记录一个奇怪的前端布局现象
前端
Json_181790144802 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
风尚云网3 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02043 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing3 小时前
React核心功能详解(一)
前端·react.js·前端框架