当前位置:网站首页>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>
推荐阅读
点赞 + 关注 + 收藏 = 学会了
边栏推荐
- docker mysql
- Story points vs. human days
- Thymeleaf dependency
- Yolov3 & yolov5 output result description
- 一般来讲,如果频繁出现inconsistent tab and space的报错
- selenium 元素定位方法
- P1908 reverse sequence pair
- 自定义事件,全局事件总线,消息订阅与发布,$nextTick
- [development environment] 010 editor tool (tool download | binary file analysis template template installation | shortcut key viewing and setting)
- Quick analysis: easy to share the Internet
猜你喜欢

你知道Oracle的数据文件大小有上限么?

Pycharm连接远程服务器

selenium 元素定位方法

2022家用投影仪首选!当贝F5强悍音画效果带来极致视听体验

In 2021, the global styrene butadiene styrene (SBS) revenue was about $3722.7 million, and it is expected to reach $5679.6 million in 2028

Will your sleep service dream of the extra bookinfo on the service network

Development skills of rxjs observable custom operator

Tencent cloud tstor unified storage passed the evaluation of the first batch of basic file storage capabilities of the ICT Institute

关于Flink框架窗口(window)函数最全解析

MQ教程 | Exchange(交换机)
随机推荐
Multi rotor aircraft control using PID and LQR controllers
How many knowledge points can a callable interface have?
Slashgear shares 2021 life changing technology products, which are somewhat unexpected
[deep learning] simple implementation of neural network forward propagation
Characteristics of selenium
Use of freemaker
Basic knowledge of QT original code
Daily learning 3
QT new project_ MyNotepad++
Qt原代码基本知识
Development and design of animation surrounding mall sales website based on php+mysql
TeamTalk源码分析之win-client
Convolutional neural network (Introduction)
Dangbei projection 4K laser projection X3 Pro received unanimous praise: 10000 yuan projector preferred
Golang quickly generates model and queryset of database tables
Packet capturing tool Fiddler learning
QT new project
快解析:轻松实现共享上网
千元投影小明Q1 Pro和极米NEW Play谁更好?和哈趣K1比哪款配置更高?
【虹科技术分享】如何测试 DNS 服务器:DNS 性能和响应时间测试