一,fabric对象的理解
原生的canvas画图操作太过繁琐,fabric.js在原生canvas方法之上封装了一层,提供更为简单但功能强大的对象模型。它负责画布的状态和渲染,并让我们直接使用“对象”。
使用abric需要先理解它对象的概念。画布是一个对象,上面的各个图案也是对象。而原生的canvas则没有这么多对象。可以看下文对比,理解一下。
1,使用原生canvas和fabric创建图形对比
当我们使用canvas画图的操作:
<template> <div class="app"> <canvas id="canvas" width="300" height="200"></canvas> </div> </template> <script> export default {
mounted() {
var canvasEl = document.getElementById("canvas"); canvasEl.style.background = 'grey' var ctx = canvasEl.getContext("2d"); ctx.fillStyle = 'red'; ctx.fillRect(100,100,20,20); }, }; </script>
看起来和原生js差不多,繁琐低效。再看fabric:
<template> <div class="app"> <canvas id="canvas" width="300" height="200"></canvas> </div> </template> <script> import {
fabric} from "fabric" export default {
mounted(){
var canvas = new fabric.Canvas("canvas",{
backgroundColor:"grey"}); var rect = new fabric.Rect({
left:100, top:100, fill:"red", width:20, height:20, }); canvas.add(rect); } } </script>
使用原生方法,我们可以在上下文ctx(一个表示整个画布位图的对象)上操作。在Fabric中,我们对对象进行操作——实例化它们,更改其属性并将其添加到画布。这些对象是Fabric土地上的一等公民。
2,使用原生canvas和fabric修改图形对比
按照1中的说法,原生canvas中我们只能获取到表示整个画布位图的ctx对象。那如果要移动画布中的图案呢?
原生canvas需要先清除画布上的内容,然后再在目标位置画出新内容。
mounted() {
var canvasEl = document.getElementById("canvas"); canvasEl.style.background = 'grey' var ctx = canvasEl.getContext("2d"); ctx.fillStyle = 'red'; ctx.fillRect(100,100,20,20); //位移 ctx.clearRect(0,0,canvasEl.width,canvasEl.height);//整个画布内容擦除 ctx.fillRect(20,50,20,20);//新位置绘图 },
而使用fabric呢?
mounted(){
var canvas = new fabric.Canvas("canvas",{
backgroundColor:"grey"}); var rect = new fabric.Rect({
left:100, top:100, fill:"red", width:20, height:20, }); canvas.add(rect);//在画布对象上添加这个矩形 // 位移 rect.set({
left:20,top:50});//修改举行对象的位置属性 canvas.renderAll()//修改完之后重新渲染 }
画布上创建的矩形rect本身是一个对象,我们只要修改它的位置属性,就可以实现位置的移动了。理解了fabric的对象的概念,就可以开始使用了。
二,安装
npm i fabric --save
三,画布对象
<canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc;"></canvas>
import {
fabric } from 'fabric' const canvas=new fabric.Canvas("canvas", {
backgroundColor: "pink", selectionColor: "blue", selectionLineWidth: 2, // ... }); // 这里传入的是canvas的id:c,第二个参数是对象,里面可以设置画布的一些属性 //获取canvas上的所有对象 canvas.getObjects(); //在画布上添加指定的对象 canvas.add(rect); //删除指定的对象 canvas.remove(rect); }
参数的设置可以查看官网对应的api:JSDoc: Class: Canvas (fabricjs.com)
四,创建基础对象
1,Fabric.js
基础对象
在 Fabric.js
中有以下七种预定义的基础对象。
fabric.Rect 矩形 fabric.Circle 圆形 fabric.Triangle 三角形 fabric.Ellipse 椭圆 fabric.Line 线型 fabric.Polyline 折线 fabric.Polygon 多边形
为了方便起见,我把这七种都写出来了:
//新建画布对象 const canvas = new fabric.Canvas("canvas", {
backgroundColor: "pink", selectionColor: "blue", selectionLineWidth: 2, }); //矩形 const rect = new fabric.Rect({
left: 10, top: 10, width: 30, height: 30, fill: "yellow", }); //圆形 const circle = new fabric.Circle({
left: 50, top: 10, radius: 15, fill: "green", }); //三角形 const triangle = new fabric.Triangle({
left: 90, top: 10, width: 30, height: 30, fill: "blue", }); //椭圆 const ellipse = new fabric.Ellipse({
left: 130, top: 10, rx: 10, //短轴 ry: 15, //长轴 fill: "red", //填充颜色 stroke: "rgba(0, 0, 0, 1)", //边框颜色 }); //直线 const line = new fabric.Line([170, 25, 200, 25], {
//该数组四个值【起点x,起点y,终点x,终点y】 fill: "#5E2300", //填充颜色 stroke: "#5E2300", //笔触颜色 }); //折线 const polyline = new fabric.Polyline( [ {
x: 200, y: 10, }, {
x: 250, y: 50, }, {
x: 250, y: 180, }, ], {
fill: "transparent", stroke: "red", //笔触颜色 strokeWidth: 2, } ); // 多边形 const polygon = new fabric.Polygon( [ {
x: 200, y: 10, }, {
x: 250, y: 50, }, {
x: 250, y: 180, }, ], {
left: 100, top: 50, fill: "red", strokeWidth: 4, stroke: "green", } ); canvas.add(rect, circle, triangle, ellipse, line, polyline, polygon); //它可以添加一个,也可以一次性添加多个
实现的效果:
2,基础对象的常见属性
上文创建了其中基础对象,他们有一些属性参数,如下所示:
fill: "#5E2300", //填充颜色 stroke: "#5E2300", //笔触颜色 scaleX: 4,//x轴放大倍数 scaleY: 4,//y轴放大倍速 strokeWidth: 4, //笔触宽度 selectable: true, //是否可被选中 transparentCorners: false, //选中后的控制手柄的是否透明 cornerColor: "blue", //选中后的控制手柄颜色 hasControls: true, //选中时是否可以放大缩小 hasRotatingPoint: true, //选中时是否可以旋转 hasBorders: true, //选中时是否有边框 lockMovementX: true, //X轴是否可被移动(true为不可,因为前缀是lock) lockMovementY: true, //Y轴是否可被移动(true为不可,因为前缀是lock)
更多的属性,可以查看对应文档:JSDoc: Home (fabricjs.com)
五,操作对象
上文我们只是创建了对象,在某个时候,我们可能会想要修改那些对象。
也许某些动作将需要触发状态改变,或者播放某种形式的动画。或者,我们可能想更改某些鼠标交互时的对象属性(颜色,不透明度,大小,位置)。
Fabric和vue一样,数据驱动视图,我们只要变更对应对象的属性值,就可以驱动视图发生相应的变化。
而这些可供修改的属性,都与定位有关——left、top;尺寸——width、height;渲染——fill、opacity、stroke、strokeWidth;缩放和旋转——scaleX、scaleY、angle;甚至与翻转相关的内容——flipX、flipY和倾斜的skewX、skewY。
1,读取对象属性
obj.get('属性名')
例如,获取距离左侧的宽度:
//新建画布对象 const canvas = new fabric.Canvas("canvas", {
backgroundColor: "pink", selectionColor: "blue", selectionLineWidth: 2, }); // 多边形 const polygon = new fabric.Polygon( [ {
x: 100, y: 10, }, {
x: 250, y: 10, }, {
x: 250, y: 180, }, {
x: 150, y: 180, }, ], {
left: 100, top: 50, fill: "red", strokeWidth: 4, stroke: "green", perPixelTargetFind: true, } ); canvas.add(polygon); console.log("获取距离左侧距离", polygon.get("left"));
2,设置对象属性
obj.set("属性名",新的属性值)
这个set还支持链式调用,并且,在canvas.add(polygon);之前或者之后调用,都是可以的:
polygon.set("fill", "blue").set("stroke", "red");//将上文的多边形填充和边框颜色变更
或者obj.set传入属性对象也是可以的
obj.set({
属性名:属性值})
3,自定义原型对象属性方法
在fabric中的大多数对象都从根fabric.Object
继承。 fabric.Object
几乎代表一个二维形状,位于二维画布平面中。它是一个具有left / top和width / height属性以及一系列其他图形特征的实体。我们在对象上看到的那些属性(fill、stroke、angle、opacity、flip *等)对于所有从fabric.Object
继承的Fabric对象都是共有的。 这种继承使我们可以在fabric.Object
上定义方法,并在所有子“类”之间共享它们。例如,如果要在所有对象上都具有getWidth
方法,则只需在fabric.Object.prototype
上创建它:
fabric.Object.prototype.getWidth = function () {
return this.get("width"); }; //新建画布对象 const canvas = new fabric.Canvas("canvas", {
backgroundColor: "pink", selectionColor: "blue", selectionLineWidth: 2, }); // 多边形 const polygon = new fabric.Polygon( [ {
x: 100, y: 10, }, {
x: 250, y: 10, }, {
x: 250, y: 180, }, {
x: 150, y: 180, }, ], {
left: 100, top: 50, fill: "red", strokeWidth: 4, stroke: "green", perPixelTargetFind: true, } ); canvas.add(polygon); console.log("获取宽度", polygon.getWidth());
六,Image对象
图像对象和基础对象又有所不同,因为它需要开发者额外导入图像资源。
这里需要区分两种情况。
1,document上有已经渲染的图像
这种写法需要等图像已经渲染出来了,才能创建fabric对象。所以我把创建canvas放在image的load方法内部了。
<template> <div id="app"> <!-- 1、创建 canvas 元素 --> <canvas width="400" height="400" id="canvas" style="border: 1px solid #ccc" ></canvas> <img src="./hq-wmyd.png" alt="picture" id="img" width="100" height="auto" @load="imageLoad" /> </div> </template> <script> //引入fabric import {
fabric } from "fabric"; export default {
name: "App", components: {
}, mounted() {
}, data() {
return {
}; }, methods: {
imageLoad() {
const canvas = new fabric.Canvas("canvas"); canvas.setBackgroundColor("rgb(100,200,200)"); const imgElement = document.getElementById("img"); const imgInstance = new fabric.Image(imgElement, {
left: 100, top: 100, angle: 45, opacity: 0.6, }); console.log(imgInstance); canvas.add(imgInstance); }, }, }; </script> <style scoped lang="scss"></style>
2,采用图片地址的方式
const canvas = new fabric.Canvas("canvas"); canvas.setBackgroundColor("rgb(100,200,200)"); fabric.Image.fromURL( "https://i.niupic.com/images/2022/10/15/a9pJ.png", (oImg) => {
canvas.add(oImg); } );
实现的效果均是如下:
七,路径对象path
上文我们已经能够绘制基本的图案了。
如果想要画出更复杂的图案,则需要引入path。
Fabric中的路径非常类似于SVG <path>
元素。它们使用相同的命令集。Fabric中的路径代表可以用其他方式填充,描边和修改的形状轮廓。路径由一系列命令组成,这些命令实际上模仿了笔从一个点到另一个点的过程。借助“移动”,“线”,“曲线”或“弧”等命令,路径可以形成难以置信的复杂形状。
const canvas = new fabric.Canvas("canvas"); canvas.setBackgroundColor("rgb(100,200,200)"); const path = new fabric.Path( `M8870 5431 c-20 -11 -46 -38 -60 -63 l-25 -43 -5 -1985 c-5 -1969 -5 -1985 15 -2029 36 -80 41 -81 412 -81 l323 0 29 57 c98 194 293 384 499 487 81 41 217 83 326 102 147 25 406 16 538 -19 301 -79 541 -276 674 -553 l45 -94 421 0 421 0 63 31 c88 43 186 135 221 207 l28 57 3 728 3 728 -35 104 c-45 134 -88 218 -199 390 -191 296 -1019 1641 -1061 1723 -76 150 -232 238 -466 262 -64 6 -479 10 -1119 10 -970 -1 -1018 -2 -1051 -19z m1991 -291 c171 -17 279 -58 309 -117 8 -15 62 -107 119 -203 281 -475 476 -823 537 -961 26 -58 39 -103 42 -146 4 -58 2 -64 -25 -92 -16 -16 -47 -34 -69 -40 -55 -15 -2238 -15 -2299 0 -52 13 -119 67 -144 118 -40 79 -43 122 -39 731 3 577 3 586 25 632 13 29 35 55 55 68 32 19 48 20 709 20 393 0 720 -4 780 -10z m1605 -3111 c49 -45 54 -72 54 -294 0 -236 -7 -266 -64 -290 -71 -30 -157 -13 -206 39 -24 26 -25 34 -28 173 -7 312 33 409 166 400 38 -3 59 -10 78 -28z` ); let commonObj = {
left: 10, top: 10, fill: "#5E2300", scaleX: 0.01, scaleY: 0.01, }; canvas.add(path.set(commonObj));
创建路径的流程是:实例化fabric.Path对
象,并向其传递一串路径指令。虽然看起来很神秘,但实际上很容易理解。 “ M”表示“移动”命令,并指示隐形笔移动到第一点。 “ L”代表“线”,使笔画一条线到下一点。然后,另一个“ c”创建一条到另一点的贝塞尔曲线。最后,“ z”告诉强制绘图笔关闭路径并最终确定形状。
由于fabric.Path
就像Fabric中的任何其他对象一样,我们也能够更改其某些属性。
可以看到,路径是很多的点数据,所以通常我们很少会手动创建Path实例,而是使用Fabric的内置SVG解析器来获取路径。
上面代码实现的效果:
八,文本对象
fabric提供的文本对象支持多行输入、文字对齐方式选择、文字背景设置、文本修饰、文本行高、设置字间距、修改样式、富文本(支持标签)、在 canvas
进行输入编辑。 常用的创建文本的方法如下,第一个参数是文本内容,第二个则是文本的属性对象:
const canvas = new fabric.Canvas("canvas"); canvas.setBackgroundColor("rgb(100,200,200)"); const txt = new fabric.Text('test', {
left: 140, // 位置 top: 140, shadow: 'rgba(0,0,0,0.3) 15px 15px 15px', // 阴影 fontFamily: 'Hoefler Text', // 字体 stroke: '#ff1318', // 画笔颜色 strokeWidth: 2, // 画笔粗度 fill: '#0f0', //填充颜色 fontSize: 60, // 字体大小 }); canvas.add(txt);
实现的效果:
九,组的概念
上文讲的都是单个元素的创建和操作,除此之外,fabric也提供了将创建的对象进行组合的方法 group
,将几个对象进行组合成为一个新的对象之后进行操作:
const canvas = new fabric.Canvas("canvas"); canvas.setBackgroundColor("rgb(100,200,200)"); const rect = new fabric.Rect({
//自己对象的属性可以单独设置 width: 30, height: 30, fill: "yellow", }); const ellipse = new fabric.Ellipse({
rx: 10, //短轴 ry: 15, //长轴 fill: "red", //填充颜色 stroke: "rgba(0, 0, 0, 1)", //边框颜色 }); const group = new fabric.Group([ rect, ellipse ], {
//公用的属性可以设置到这里来 left: 0, top: 0, }); canvas.add(group);
实现的效果如下图:
而如果需要设置对象在组合中的位置,可以在创建对象的时候设置位置:
const rect = new fabric.Rect({ + left: 15, + top: 10,//这里设置位置,是以groups的左上角为基准的相对坐标值 width: 30, height: 30, fill: "yellow", });
到此这篇fabric操作canvas绘图-(一)基础使用的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/te-jc/10956.html