当前位置:网站首页 > 软件测试基础 > 正文

fabric操作canvas绘图-(一)基础使用

一,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绘图-(一)基础使用的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • 掌控网页新时代:Grav - 简单、快速、灵活的文件基础Web平台2024-12-03 07:00:10
  • 色彩理论基础2024-12-03 07:00:10
  • VPN原理入门(非常详细)从零基础入门到精通,看完这一篇就够了2024-12-03 07:00:10
  • 手机中了病毒怎么清理,简单几步教你解决!零基础入门到精通,收藏这篇就够了2024-12-03 07:00:10
  • 色彩理论基础2024-12-03 07:00:10
  • reatc的几个基础的hooks2024-12-03 07:00:10
  • docker基础(六)-目录挂载2024-12-03 07:00:10
  • docker基础(二)-安装软件2024-12-03 07:00:10
  • docker基础(一)-window下安装docker2024-12-03 07:00:10
  • 计算机基础软硬件知识(基础的计算机硬件知识)2024-12-03 07:00:10
  • 全屏图片