昆明做网站建设的公司,易语言如何做代刷网站,网站横幅背景图片,wordpress添加投稿背景
标注的几何#xff0c;有时需要一些定制化的渲染样式#xff0c;例如#xff0c;线中间展示箭头#xff0c;表示方向。本期教程教大家如何实现fabric几何定制化渲染。
带箭头的线
fabric提供了一些原生的几何#xff0c;例如Point、Polyline、Polygon。同时提供了…背景
标注的几何有时需要一些定制化的渲染样式例如线中间展示箭头表示方向。本期教程教大家如何实现fabric几何定制化渲染。
带箭头的线
fabric提供了一些原生的几何例如Point、Polyline、Polygon。同时提供了一些抽象的实体如Object、Path。
如果使用原生的几何可配置的样式是有限的。
比如Point的配置是
{radius: 5,stroke: rgba(0,0,0,1),strokeWidth: 2,fill: rgba(255,0,0,1)
}
Polyline的配置是
{stroke: rgba(0,0,0,1),strokeWidth: 5
}
Polygon的配置是
{fill: rgba(255,0,0,0,3),strokeWidth: 1
}
可见这些线宽、线颜色、填充色等并不能实现箭头样式需要对这些类进行扩展。
fabric提供了方法可以扩展原生几何代码如下
export const NewPolyline fabric.util.createClass(fabric.Polyline, {type: NewPolyline,initialize: function (points: any [], options: any {}) {this.callSuper(initialize, points, { ...options }); // 调用Polyline的初始化方法},_render: function (ctx: any) {// 自定义渲染每次canvas.renderAll()都会触发该方法。this.callSuper(_render, ctx);}
}
此时我们得到了一个新的fabric几何类型NewPolyline。其初始化参数和Polyline一致points是点序options里设置其样式。
而箭头样式需要在_render方法里实现。_render方法可以拿到ctx即canvas的实例我们可以利用ctx进行各种绘制操作。
注意在_render这个步骤每个几何都有自己的坐标系其坐标系原点是几何的外接矩形的中心点。
因此我们每个坐标都需要减去当前几何的width/2和height/2进行原点平移。
举个例子比如我们有一条线其参数如下
{left: 10,top: 10,points: [{x: 0, y: 0}, {x: 5, y: 0}, {x: 5, y: 5}],
}
在坐标系中如图 left和top将要素的坐标系从O移动到了O在此基础上绘制折线[[0,0],[5,0],[5,5]]。
在渲染时fabric又将坐标原点O平移到外接矩形的中心点O。
知道坐标系后我们先来求线段的中点
const points this.get(points);
const width this.get(width);
const height this.get(height);for (let i 0; i points.length; i) {const midX (points[i].x points[i 1].x) / 2 - width / 2;const midY (points[i].y points[i 1].y) / 2 - height / 2;console.log(midX, midY);
}// 结果
// -2.5, -2.5
// 2.5, -2.5
// 2.5, 2.5
看懂上面的代码你就可以以线段中心点为中心画沿着线段的三角形了代码如下
for (let i 0; i points.length - 1; i) {const midX (points[i].x points[i 1].x) / 2 - width / 2;const midY (points[i].y points[i 1].y) / 2 - height / 2;const rotate Math.atan2(points[i 1].y - points[i].y, points[i 1].x - points[i].x);ctx.moveTo(midX, midY);const firstX midX - (arrowWidth / 2) * Math.sin(rotate);const firstY midY (arrowWidth / 2) * Math.cos(rotate);ctx.lineTo(firstX, firstY);const secondX midX (arrowWidth / 2) * Math.sqrt(3) * Math.cos(rotate);const secondY midY (arrowWidth / 2) * Math.sqrt(3) * Math.sin(rotate);ctx.lineTo(secondX, secondY);const thirdX midX (arrowWidth / 2) * Math.sin(rotate);const thirdY midY - (arrowWidth / 2) * Math.cos(rotate);ctx.lineTo(thirdX, thirdY);ctx.closePath();ctx.fill();}
效果图如下 了解这个原理你就可以利用canvas的绘制操作实现任何的自定义样式。
缩放控制线宽等宽
上一章我们讲到了画布是可以拖拽和缩放的本质上是修改canvas的transform。
在每次缩放后canvas会调用renderAll方法从而调用每个几何的_render方法。在_render内我们需要重新计算strokeWidth
const strokeWidth 5;
const zoom canvas.getZoom();
this.set({strokeWidth: strokeWidth / zoom
});
这样可以保证每次缩放后线宽依然维持一个固定值。如果我们不修改线宽则会被同样得缩放。
预告
下一章我们详细聊一个极其隐蔽的问题线居中渲染。