当前位置:网站首页>Fabric.js 自由绘制圆形
Fabric.js 自由绘制圆形
2022-07-02 11:08:00 【德育处主任】
本文简介
这次要讲的是 自由绘制圆形 。
在 《Fabric.js 自由绘制矩形》 里讲到的思路,放在圆形里不太适用。
这次要做到的效果如下图所示。
<br>
<br>
思路
Fabric.js
默认的框选操作是矩形,如果需要做到上图的效果,需要做以下3步:
- 点击画布时
canvas.on('mouse:down', fn)
,创建一个圆形。 - 鼠标移动时
canvas.on('mouse:move', fn)
,圆形的大小跟随鼠标所在的位置进行缩放。 - 松开鼠标时
canvas.on('mouse:up', fn)
,确定圆形大小。
<br>
交互操作方面,我按照 PhotoShop
椭圆工具的操作逻辑。
圆形的直径是矩形的短边。
<br>
如果 “移动鼠标的坐标点” 在 点击时的坐标点 左侧或者上方,需要将圆形的左上角移到 “移动鼠标的坐标点” 。
<br>
<br>
动手实现
我在这里贴出用 原生方式 实现的代码和注释。
如果你想知道在 Vue3
环境下如何实现 Fabric.js 自由绘制矩形
,可以在 代码仓库 里查找。
<!-- 工具栏 --><div class="toolbar"> <select onchange="typeChange(this.options[this.options.selectedIndex].value)"> <option value="default">默认(框选)</option> <option value="circle">圆形</option> </select></div><!-- 画布 --><canvas id="canvas" width="800" height="800"></canvas><!-- 引入fabric.js --><script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.js"></script><script>let canvas = null // 画布对象let currentType = 'default' // 当前操作模式(默认 || 创建圆形)let downPoint = null // 按下鼠标时的坐标let upPoint = null // 松开鼠标时的坐标let currentCircle = null // 临时圆,创建圆的时候使用// 初始化画板function initCanvas() { canvas = new fabric.Canvas('canvas') canvas.on('mouse:down', canvasMouseDown) // 鼠标在画布上按下 canvas.on('mouse:move', canvasMouseMove) // 鼠标在画布上移动 canvas.on('mouse:up', canvasMouseUp) // 鼠标在画布上松开}// 画布操作类型切换function typeChange(opt) { currentType = opt switch(opt) { case 'default': // 默认框选模式 canvas.selection = true // 允许框选 canvas.selectionColor = 'rgba(100, 100, 255, 0.3)' // 选框填充色:半透明的蓝色 canvas.selectionBorderColor = 'rgba(255, 255, 255, 0.3)' // 选框边框颜色:半透明灰色 canvas.skipTargetFind = false // 允许选中 break case 'circle': // 创建矩形模式 canvas.selectionColor = 'transparent' // 选框填充色:透明 canvas.selectionBorderColor = 'transparent' // 选框边框颜色:透明度很低的黑色(看上去是灰色) canvas.skipTargetFind = true // 禁止选中 break }}// 鼠标在画布上按下function canvasMouseDown(e) { downPoint = e.absolutePointer if (currentType === 'circle') { // 使用 Fabric.js 提供的api创建圆形,此时圆形的半径是0 currentCircle = new fabric.Circle({ top: downPoint.y, left: downPoint.x, radius: 0, fill: 'transparent', stroke: 'rgba(0, 0, 0, 0.2)' }) canvas.add(currentCircle) }}// 鼠标在画布上移动function canvasMouseMove(e) { if (currentType === 'circle' && currentCircle) { const currentPoint = e.absolutePointer // 半径:用短边来计算圆形的直径,最后除以2,得到圆形的半径 let radius = Math.min(Math.abs(downPoint.x - currentPoint.x), Math.abs(downPoint.y - currentPoint.y)) / 2 // 计算圆形的top和left坐标位置 let top = currentPoint.y > downPoint.y ? downPoint.y : downPoint.y - radius * 2 let left = currentPoint.x > downPoint.x ? downPoint.x : downPoint.x - radius * 2 // 分别设置圆形的半径、top和left currentCircle.set('radius', radius) currentCircle.set('top', top) currentCircle.set('left', left) canvas.requestRenderAll() }}// 鼠标在画布上松开function canvasMouseUp(e) { upPoint = e.absolutePointer if (currentType === 'circle') { // 如果鼠标点击和松开是在同一个坐标,那就不会创建圆形(其实是把刚创建半径为0的圆形删掉) if (JSON.stringify(downPoint) === JSON.stringify(upPoint)) { canvas.remove(currentCircle) } else { if (currentCircle) { // 创建圆形(其实是把圆形边框的颜色改成 #000 currentCircle.set('stroke', '#000') } } // 完成以上操作后,临时的圆形清空掉。 currentCircle = null }}// 页面加载的生命周期,在此执行 初始化画布 的操作window.onload = function() { initCanvas()}</script>
<br>
<br>
代码仓库
<br>
<br>
推荐阅读
点赞 + 关注 + 收藏 = 学会了
边栏推荐
- Origin plots thermogravimetric TG and differential thermogravimetric DTG curves
- 2022家用投影仪首选!当贝F5强悍音画效果带来极致视听体验
- MQ教程 | Exchange(交换机)
- Launcher startup process
- Data Lake (11): Iceberg table data organization and query
- Solve the problem that openocd fails to burn STM32 and cannot connect through SWD
- go操作redis
- MySQL 45 lecture - learning from the actual battle of geek time MySQL 45 Lecture Notes - 04 | easy to understand index (Part 1)
- Design and implementation of car query system based on php+mysql
- NLA自然语言分析,让数据分析更智能
猜你喜欢
博睿数据一体化智能可观测平台入选中国信通院2022年“云原生产品名录”
全屋Wi-Fi:一个谁也解决不好的痛点?
TeamTalk源码分析之win-client
Yyds dry goods inventory software encryption lock function
Penetrate the remote connection database through the Intranet
关于Flink框架窗口(window)函数最全解析
Just 1000 fans, record it
测试框架TestNG的使用(二):testNG xml的使用
Whole house Wi Fi: a pain point that no one can solve?
[development environment] 010 editor tool (tool download | binary file analysis template template installation | shortcut key viewing and setting)
随机推荐
跨服务器数据访问的创建链接服务器方法
卷积神经网络(入门)
Tencent cloud tstor unified storage passed the evaluation of the first batch of basic file storage capabilities of the ICT Institute
P1908 逆序对
go操作redis
Start to write a small demo - three piece chess
< schematic diagram of oral arithmetic exercise machine program development> oral arithmetic exercise machine / oral arithmetic treasure / children's math treasure / children's calculator LCD LCD driv
Yolov3 & yolov5 output result description
Who is better, Qianyuan projection Xiaoming Q1 pro or Jimi new play? Which configuration is higher than haqu K1?
什么是 eRDMA?丨科普漫画图解
Will your sleep service dream of the extra bookinfo on the service network
Data consistency between redis and database
给Android程序员的一些面试建议「建议收藏」
2022 home projector preferred! Dangbei F5 brings the ultimate audio-visual experience with its powerful audio-visual effect
Solve the problem that openocd fails to burn STM32 and cannot connect through SWD
Pychart connects to the remote server
Getting started with QT - making a simple calculator
uni-app中使用computed解决了tab切换中data()值显示的异常
[deep learning] simple implementation of neural network forward propagation
无主灯设计:如何让智能照明更加「智能」?