canvas-绘图库fabric.js简介

一般情况下简单的绘制,其实canvas原生方法也可以满足,比如画个线,绘制个圆形、正方形、加个文案。

  let canvas = document.getElementById('canvas');canvas.width = 1200;canvas.height = 600;canvas.style.width = '1200px';canvas.style.height = '600px';let ctx = canvas.getContext('2d');ctx.moveTo(400, 100);ctx.lineTo(400, 200);ctx.lineTo(500, 200);ctx.strokeStyle = "#00F";ctx.stroke();ctx.beginPath();ctx.arc(150, 150, 100, 0, 2 * Math.PI, true);ctx.fillStyle = '#ccc';ctx.fill();ctx.beginPath();let str1 = '苟利国家生死以,';let str2 = '岂因祸福避趋之!';ctx.font = '50px Microsoft Yahei';ctx.strokeStyle = 'red';ctx.textAlign = 'center';ctx.strokeText(str1, 800, 50);ctx.font = '50px SimHei';ctx.fillStyle = 'blue';ctx.textAlign = 'center';ctx.fillText(str2, 800, 100);//获取文本的宽度,以便以后能动态的使文本居中。let strWidth = ctx.measureText(str2).width;console.log(strWidth);

看效果图
在这里插入图片描述
如果真的只是这点需求,原生方法也很好,省的加载一个js库。不过现实往往还是很残酷的,怎么可能这么简单,这里都没有交互,比如在现有的图形上做位移、拖拽等等,复杂度就上来了,这时一个好的canvas js库就很有必要了。
fabric.js 算是我用到过的比较全面且好用的一个canvas js库;
先上代码:

const data = {line: ['1648.607594936709', '654.1772151898734', '2100.253164556962', '1290.126582278481'],area: ["1604.0506329113923", "607.5949367088607", "1648.607594936709", "654.1772151898734", "2100.253164556962", "1290.126582278481"
, "2211.645569620253", "1429.873417721519", "285.56962025316454" , "1429.873417721519" , "617.7215189873417" , "662.2784810126582"]
};
// 可以看出上面数据一个是画线,一个是画不规则区域,这是实际项目中用到的数据,拿到这里自有妙处,后面会说

fabric.js使用

import { fabric } from ‘fabric’;

// canvasDraw是canvas的 id
const canvasBox = new fabric.StaticCanvas('canvasDraw', {backgroundColor: "transparent"});// 这个是设置// canvas.style.width 和 canvas.width// canvas.style.height 和 canvas.height
canvasBox.setDimensions({width: 600,height: 300
});
// 下面方法等同于 setDimensions
// canvasBox.setWidth(width);
// canvasBox.setHeight(height);// 这个是设置的 canvas.style.width 和 canvas.style.height
canvasBox._setCssDimension('width', 2400);
canvasBox._setCssDimension('height', 1500);

到此fabric初始化就算完成了,这里有个很重要的点,官方文档和几乎所有写fabric教学的博客都没有讲,那就是如何将canvas.style.width 和 canvas.width 赋予不同的数值,这是个很实用的点,因为坐标点是按canvas.width来的,但是我们的canvas.style.width必须和设计保持一致
比如说:我们需要在一张图片上做绘制,那坐标点是从图片原图上标注的,而设计不可能按原图大小展示,这时就会出现坐标点和canvas.style.width不一致,有两个方法解决这个问题:
1、坐标点根据 canvas.style.width / img.width 的比率做调整
2、canvas.width 和 img.width保持一致,canvas.style.width 和 设计稿 width一致
很显然第二个方案更简单且实用
既然官网没提供方法那我们就看源码都做了什么,因为canvas.width是必然要设置的
我们发现setDimensions时调用了 _setBackstoreDimension 和 _setCssDimension
在这里插入图片描述
很明显这里是canvas.width
在这里插入图片描述
而这里是canvas.style.width
在这里插入图片描述
今天先简单点,只看画线和画不规则图形

function drawLine(arr, color, opacity) {// [x1, y1, x2, y2]const line =  new fabric.Line(arr, {strokeWidth: 10, //线宽stroke: color, //线的颜色selectable: false,opacity: opacity});this.canvasBox.add(line);
}
function drawPolygon(arr, color, opacity) {const newArr = formatData(arr);const polygon = new fabric.Polygon(newArr,{fill: color,strokeWidth: 1,stroke: "#000",opacity: opacity});this.canvasBox.add(polygon);
}
function formatData(arr) {// 将 [100,50,200,40] 坐标点转为 {x: 100, y: 50}let newArr = [];arr.forEach((val, i) => {i = i + 1;// 偶数不操作if ((i % 2) !== 0) {newArr.push({x: parseInt(val),y: parseInt(arr[i])});}});return newArr;
}

这时大家就会看到 我有个 parseInt的操作,因为当我使用原数据绘制时,线可以出来但Polygon却没有,搞得很郁闷,查了很长时间,最后当我盯着数据发呆时,看着长长的小数位 突发奇想,于是parseInt诞生了,页面也能看到区域了,真的是坑,这个点不做项目是绝无可能发现的。
也是我今天冒着延期项目也要搞这么一篇文章的原因,虽然fabric知识点不多但绝对满满的干货,更是告诉大家遇到问题后不要怕、更不能放弃,永远都能找到解题的方法,条条大路通罗马,一条不行就换一条,总会解决的!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/83386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R绘制箱线图

代码大部分来自boxplot()函数的帮助文件,可以通过阅读帮助文件,调整代码中相应参数看下效果,进而可以理解相应的作用,帮助快速掌握barplot()函数的用法。 语法 Usage(来自帮助文件) barplot(height, ...)## Default S3 method: …

就只说 3 个 Java 面试题

在面试时,即使是经验丰富的开发人员,也可能会发现这是一些很棘手的问题: 1、Java中“transient”关键字的用途是什么?如何才能实现这一目标? 在 Java 中,“transient”关键字用于指示类的特定字段不应包含…

使用RKDevTool将update.img完整镜像进行解包,得到单独分区的镜像

(1)使用开发工具高级功能的解包 导入xx.img,然后点击解包(2)在Output/Android/Image得到想要的image

Linux关于memory cgroup的几个要点

概述 本文讲述memory cgroup比较容易误解的一些逻辑,如果不太经常使用和解决问题的话,对于memory cgroup的认知会比较浅显:cgroup memory用来限制进程的内存使用,但是我们进一步想如下的问题: 进程的内存可以分很多类…

Vue的路由使用,Node.js下载安装及环境配置教程 (超级详细)

前言&#xff1a; 今天我们来讲解关于Vue的路由使用&#xff0c;Node.js下载安装及环境配置教程 一&#xff0c;Vue的路由使用 首先我们Vue的路由使用&#xff0c;必须要导入官方的依赖的。 BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务https://www.bootcdn.cn/ <…

IP协议的相关特性

IP协议相关特性 报头结构 报文结构解释 4位版本号:指定IP协议的版本,对于IPV4来说,就是四位. 4位首部长度:IP头部的长度是多少个32bit,也就是Length4的字节数,4bit表示的最大的数是15,因此IP头部最大长度是60. 8位服务类型:3位优先权字段&#xff08;已经弃用&#xff09;&…

安全生产知识竞赛活动小程序界面分享

安全生产知识竞赛活动小程序界面分享

linux内核分析:进程通讯方式

信号 一旦有信号产生,我们就有下面这几种,用户进程对信号的处理方式。 1.执行默认操作。Linux 对每种信号都规定了默认操作,例如,上面列表中的 Term,就是终止进程的意思。Core 的意思是 Core Dump,也即终止进程后,通过 Core Dump 将当前进程的运行状态保存在文件里面…

Python画图系列——折线图

好看的折线图 import numpy as np import matplotlib.pyplot as plt# 生成随机数据 # np.random.seed(42) # 设置随机种子以确保可重复性 sample_numbers np.arange(1, 21) # 生成1到20的样本编号random_data np.random.rand(20) # 生成20个随机数&#xff0c;范围在0到1之…

淘宝商品详情数据采集

淘宝商品详情数据采集的方法如下&#xff1a; 确定采集目标&#xff1a;明确要采集的商品信息&#xff0c;如商品标题、价格、销量、评论、图片等。选择采集工具&#xff1a;可以选择Scrapy框架、Java的WebMagic框架等。编写爬虫程序&#xff1a;进入目标文件夹&#xff0c;输…

无涯教程-JavaScript - POWER函数

描述 POWER函数返回加到幂的数字的输出。 语法 POWER (number, power)争论 Argument描述Required/OptionalNumber 基数。 它可以是任何实数。 RequiredPowerThe exponent to which the base number is raised.Required Notes 可以使用" ^"运算符代替POWER来指示…

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

二、搭建Java环境

搭建Java环境 搭建Java环境1.1.下载JDK1.2.在Win10下配置JDK环境 —————————————————————————————————————————————————— ———————————————————————————————————————————————…

python 冒泡排序以及鸡尾酒排序

冒泡排序 就是一次循环&#xff0c;两两数据比较&#xff0c;将最大值放入末尾&#xff0c;此时找到了最大值&#xff0c;然后进行二次三次等循环&#xff0c;直到排序结束 冒泡排序代码 def bubble_sort_v1(array[]):for i in range(len(array)-1):for j in range(len(arra…

【CANoe/CANalyzer脚本】通过CAPL发送NM帧报文测试网络管理

优质博文推荐阅读&#xff08;单击下方链接&#xff0c;即可跳转&#xff09;&#xff1a; Vector工具链 CAN Matrix DBC CAN Matrix Arxml 一、在CANoe/CANalyzer中创建Program Node 在Measurement Setup中&#xff0c;创建Program Node&#xff1b; 接着导入下面的Demo:N…

D数树,牛客小白月赛78,思维

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 262144K&#xff0c;其他语言524288K 64bit IO Format: %lld 题目描述 “开导&#xff01;” 众所周知&#…

echarts 轴文字内容太长导致显示不全解决方案

情况&#xff1a;Y轴内容是文字&#xff0c;内容太长可能会系那是不全。调整grid会导致短数据前的留白过于多。 解决方案&#xff1a; 方法一&#xff1a; 首先可以配置grid自适应 &#xff0c; containLabel 属性设置true &#xff08;这常用于『防止标签溢出』的场景&…

树、二叉树、森林的相互转化

目录 一、树>二叉树 二、二叉树>树 三、二叉树>森林 四、森林>二叉树 一、树>二叉树 ①兄弟相连 ②断开每个节点除与左孩子之外的连线 ③调整树为二叉树 二、二叉树>树 ①如果一个节点有父节点&#xff0c;将其右孩子与父节点相连&#xff0c;右孩子…

3D模型格式转换工具HOOPS Exchange协助Epic Games实现CAD数据轻松导入虚幻引擎

一、面临的挑战 Epic Games最为人所知的身份可能是广受欢迎的在线视频游戏Fortnite的开发商&#xff0c;但它也是虚幻引擎背后的团队&#xff0c;虚幻引擎是一种实时3D创作工具&#xff0c;为世界领先的游戏提供动力&#xff0c;并且也被电影电视、建筑、汽车、制造、模拟等领…

Python计算机二级知识点整理

1.当一个进程在运行过程中释放了系统资源后要调用 唤醒进程原语 唤醒进程原语是把进程从等待队列里移出到就绪队列并设置进程为就绪状态&#xff0c;当一个进程在运行过程中释放了系统资源后进入就绪状态&#xff0c;调用唤醒进程原语。 2. 3. 4.在希尔排序法中&#x…