Fabric.js 铅笔笔刷

news2025/8/22 6:20:55

本文简介

点赞 + 关注 + 收藏 = 学会了


fabric.js 的铅笔其实是继承基础画笔的一个工具,在基础画笔的基础上多了“拐角平滑度”等配置项。

本文讲解铅笔的基础用法以及常用事件。



常规配置

真实世界的铅笔有不同的型号,颜色的深浅、笔芯的硬度都是不同的。

fabric.js 中,铅笔同样有不同配置。


开启绘图模式

要使用铅笔的话,首先要开启“绘图模式”。

下面这段代码是本文的基础代码,之后配置到的铅笔属性和铅笔相关的方法都是基于这段代码的基础。

引入 fabric.js 的代码我就不写了,如果不知道如何引入可以查看 《Fabric.js 从入门到膨胀》。

file

<canvas id="canvas" width="500" height="400" style="border: 1px solid #ccc;"></canvas>

<script>
  var canvas = new fabric.Canvas('canvas', {
    isDrawingMode: true // 绘图模式
  })
</script>

isDrawingMode 设置为 true 就可以开启绘图模式了。此时在画布上按着鼠标左键就能绘画。


注册铅笔

要使用铅笔工具,需要将 canvas.freeDrawingBrush 设置成铅笔。

// 省略部分代码

var canvas = new fabric.Canvas('canvas', {
  isDrawingMode: true // 绘图模式
})

// 实例化铅笔
let pencilBrush = new fabric.PencilBrush(canvas)
// 将画布的画笔设置成铅笔
canvas.freeDrawingBrush = pencilBrush

需要注意的是,在 new fabric.PencilBrush(canvas) 中需要传入 canvas

除了在实例化时期传入 canvas ,还可以调用 initialize 方法传入。

// 省略部分代码

// 创建铅笔
let pencilBrush = new fabric.PencilBrush()
// 初始化铅笔
pencilBrush.initialize(canvas)
// 将画笔设置成铅笔
canvas.freeDrawingBrush = pencilBrush

设置铅笔颜色

要设置的属性是 color

file

// 省略部分代码

pencilBrush.color = 'pink'

除了设置关键字,还可以通过十六进制的颜色值、rgba等方式进行设置。

比如 pencilBrush.color = 'rgba(0, 0, 0, 0.1)' 就能设置一个具有透明度的黑色的画笔。


设置铅笔粗细

使用 width 可以设置铅笔的粗细,赋的值是数值类型的。

file

// 省略部分代码

pencilBrush.width = 10

阴影

需要使用 fabric.Shadow 创建阴影,再赋值给 shadow

为了演示方便,我把铅笔的 width 设置成 10

file

// 省略部分代码

// 加粗铅笔,方便演示
pencilBrush.width = 10

// 设置阴影
pencilBrush.shadow = new fabric.Shadow({
  blur: 10, // 羽化程度
  offsetX: 10, // x轴偏移量
  offsetY: 10, // y轴偏移量
  color: '#30e3ca' // 投影颜色
})

阴影 fabric.Shadow 配置项其实还有很多,这个例子主要配置了以下4个属性

  • blur: 羽化程度,接收数值类型的值。
  • offsetX: 阴影在x轴的偏移量,正值往右,负值往左。
  • offsetY: 阴影在y轴的偏移量,正值往下,负值往上。
  • color: 阴影颜色,可以使用颜色关键字、十六进制、rgba等。

虚线

可以通过 strokeDashArray 将铅笔画出来的线条设置成虚线。

strokeDashArray 的值是一个数值类型的数组,数组可以接收1个或多个元素。


当只有1个元素时,虚线和实线的长度都相等。

file

// 省略部分代码

pencilBrush.strokeDashArray = [10]

当存在2个元素时,第一个元素代表实线长度,第二个元素代表虚线的长度。

file

// 省略部分代码

pencilBrush.strokeDashArray = [30, 10]

从上图可以看出,每段实线的长度是30,每段虚线的长度是10。


如果是3个参数以上的情况,就会一直“轮回”

file

// 省略部分代码

pencilBrush.strokeDashArray = [10, 20, 30]

上面代码的情况是这样的

实线10, 虚线20, 实线30, 虚线10, 实线20, 虚线30, 实线10, ......

如果是4个、5个以上的参数,也是这样一直循环下去。


线帽

线帽就是线条两端的样式,可以使用 strokeLineCap 设置线帽样式,可选值有 buttroundsquare

默认是 round ,也就是圆形线帽。

file

// 省略部分代码

pencilBrush.width = 10 // 加粗
pencilBrush.strokeLineCap = 'round' // 修改线帽

如果 square 就是方形的头

file

// 省略部分代码

pencilBrush.width = 10 // 加粗
pencilBrush.strokeLineCap = 'square' // 修改线帽

最后一个是无线冒 butt

file

// 省略部分代码

pencilBrush.width = 10 // 加粗
pencilBrush.strokeLineCap = 'butt' // 修改线帽

看上去 buttsquare 好像有点像,但其实是不一样的。

如果线段长度一样,squareround 都会在线的两端加上线帽,会增长线的长度。


角落风格

比如字母 V 的尖尖就是“拐角”。

fabric.js 的铅笔可以通过 strokeLineJoin 属性设置拐角,支持 bevel 斜面、 round 圆形、 miter 斜面 三个属性。

// 省略部分代码

pencilBrush.strokeLineJoin = 'miter', // "bevel" 斜面, "round" 圆形, "miter" 斜面

最大斜接长度

strokeMiterLimit 属性的设置适用于 strokeLineJoinmiter 的情况。

pencilBrush.strokeMiterLimit = 20

拐角平滑度

这是一个很有意思的属性: decimate

通过设置 decimate 可以修改拐角的平滑度,数值越大就越平滑。

file

pencilBrush.width = 5 // 加粗
pencilBrush.decimate = 40

禁止超出画布

如果将铅笔的 limitedToCanvasSize 属性设置为 true ,在绘制的过程中画笔就不能超出画布了。

file

// 省略部分代码

pencilBrush.width = 5 // 加粗
pencilBrush.limitedToCanvasSize = true // 禁止画笔超出画布

绘制直线

使用铅笔时,默认按住 shift 键可以绘制直线

file

如果你想修改画直线的组合键,可以设置 straightLineKey 属性。

// 省略部分代码

pencilBrush.straightLineKey = 'shiftKey'

straightLineKey 支持以下配置:

  • shiftKey: shift键,默认
  • altKey: alt键
  • ctrlKey: ctrl键
  • 'none'、'undefined'、'null': 取消组合键


事件

fabric.js 的铅笔提供了一些基础事件,有的好用,有的不好用。。。

准备生成线路时:before:path:created

// 省略部分代码

canvas.on('before:path:created', opt => {
  console.log(opt.path)
})

线路生成完毕时:path:created

// 省略部分代码

canvas.on('path:created', function(opt) {
  console.log(opt.path)
})

鼠标点击时:onMouseDown

// 省略部分代码

pencilBrush.onMouseDown = function(t, e) {
  console.log(t)
  console.log(e)

  this.canvas._isMainEvent(e.e) &&
  (
    this.drawStraightLine = e.e[this.straightLineKey],
    this._prepareForDrawing(t),
    this._captureDrawingPath(t),
    this._render()
  )
}

参数 t 是鼠标点击时的坐标 {x, y}

参数 e 包含事件本身,还有坐标点。

可以将 te 输出到控制台看看。


onMouseDown 事件最好使用普通函数,而且要在最后写上这两句:

this._prepareForDrawing(t)
this._render()

鼠标移动时:onMouseMove

pencilBrush.onMouseMove = function(t, e) {
  console.log(t)
  console.log(e)

  if (
    this.canvas._isMainEvent(e.e) && (this.drawStraightLine = e.e[this.straightLineKey],
    (!0 !== this.limitedToCanvasSize || !this._isOutSideCanvas(t)) && this._captureDrawingPath(t) && 1 < this._points.length)
  ) {
    if (this.needsFullRender()) {
      this.canvas.clearContext(this.canvas.contextTop)
      this._render()
    }
    else {
      var i = this._points
        , r = i.length
        , n = this.canvas.contextTop

      this._saveAndTransform(n)
      this.oldEnd && 
        (
          n.beginPath(),
          n.moveTo(this.oldEnd.x, this.oldEnd.y)
        )

      this.oldEnd = this._drawSegment(n, i[r - 2], i[r - 1], !0)
      n.stroke()
      n.restore()
    }
  }
}

鼠标松开时:onMouseUp

pencilBrush.onMouseUp = function(t) {
  console.log(t)

  return !this.canvas._isMainEvent(t.e) || 
    (
      this.drawStraightLine = !1,
      this.oldEnd = void 0,
      this._finalizeAndAddPath(),
      !1
    )
}


代码仓库

⭐ 铅笔



推荐阅读

👍《Fabric.js 从入门到_ _ _ _ _ _》

👍《Fabric.js 使用图片遮盖画布(前景图)》

👍《Fabric.js 设置容器类名要注意这几点》

👍《Fabric.js 自定义子类,创建属于自己的图形》


点赞 + 关注 + 收藏 = 学会了 代码仓库

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

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

相关文章

90后,27岁转行软件测试,从月入3000+到月薪过万,打开了人生新篇章~

承蒙时光不弃&#xff0c;感谢努力的自己。以前总是在某些鸡汤文中看到这句话&#xff0c;当时觉得过于矫情&#xff0c;而如今当我突破重重困难成功转行&#xff0c;收获了更好的人生后&#xff0c;才发自内心的也有了这样的感叹。 几个月的努力和辛劳&#xff0c;一时之间难以…

转互联网好难,如何避免无效转行?

如果你现在是在传统行业工作&#xff0c;想转行互联网&#xff0c;应该怎么做呢&#xff1f; 很多人经常会担心自己的行业、专业、年龄等等会是障碍&#xff0c;或者自己没有经验&#xff0c;去面试的时候公司却都需要相关经验的人&#xff0c;怎么办呢&#xff1f; 这篇文章…

图形驱动软件栈

图形驱动软件栈 HINZER&#xff0c;2022年&#xff0c;我在北京。芯片设计行业&#xff0c;GPU 固件和驱动开发&#xff0c;对嵌入式系统感兴趣。 1 说明背景 1.1 近来想法 做了一段时间的 GPU 固件和驱动开发&#xff0c;加上平时学习的一些零散的知识&#xff0c;最近打算整…

【Web前端HTML5CSS3】06、盒模型

六、盒模型 1、文档流&#xff08;normalflow&#xff09; 网页是一个多层的结构&#xff0c;一层摁着一层 通过 CSS 可以分别为每一层来设置样式&#xff0c;作为用户来讲只能看到最顶上一层 这些层中&#xff0c;最底下的一层称为文档流 文档流是网页的基础我们所创建的元…

牛客java刷题知识点总结(八)

方法调用 类中变量&#xff1a; 除了private权限外&#xff0c;其他权限的变量&#xff08;没有表示默认default&#xff09;&#xff0c;均可以用“对象.变量名”来调用。对于private变量&#xff0c;即使使用static&#xff0c;也不能用“类.变量名”来调用私有变量。只能通过…

UID走私:一种在线跟踪用户的新技术

©网络研究院 几十年来&#xff0c;广告商和网络追踪者已经能够在用户访问的所有网站上汇总用户信息&#xff0c;主要是通过在用户的浏览器中放置第三方cookies。 两年前&#xff0c;几个优先考虑用户隐私的浏览器开始默认屏蔽所有用户的第三方cookies。 对于那些代表其…

2022年转行编程选哪门语言?这份报告给你答案!

本报告展示了 JetBrains &#xff08;IntelliJ IDEA的开发公司&#xff09;于2021年进行的第五次年度开发者生态系统调查的综合结果。来自 183 个国家或地区的 31,743 名开发者帮助我们绘制了开发者社区版图。 本文将摘录部分个人觉得有价值的报告&#xff0c;从全球视角以国内…

AI-多模态-2021:Stable Diffusion【根据文本生成图像】【开源】【目前开源模型中最强】

最近大火的Stable Diffusion也开源了(20220823); 我也本地化测试了一下效果确实比Dall-E mini强太多了&#xff0c;对于我们这些玩不上Dall-E2的这个简直就是就是捡钱的感觉&#xff0c;当然后期跑起来&#xff0c;稍微不注意显存就炸了。 这里我写一下安装过程&#xff0c;具…

Fabric.js 限制边框宽度缩放

本文简介 点赞 关注 收藏 学会了 使用 fabric.js 在某些情况下你可能需要固定元素边框的宽度&#xff0c;仔细看文档你会发现 fabric.js 已经为我们提供了这个功能。本文简单介绍一下这个功能。 实现方法 先揭晓答案&#xff0c;将元素的 strokeUniform 属性设置为 true 后…

适合贵校的核心营销讯息

香港 (Xinwengao.com) — 优秀的学校具备策略来提升形象、提高学生的成功率、改善收生&#xff08;和重新入学&#xff09;的成果。这包括为你的学校定下营销讯息。大多数学校都具备自己的营销策略&#xff0c;但很少有营销讯息。一个有力的营销讯息可大大地支援营销策略。 即…

避坑细节拉满!阿里p8技术官私传:MyBatis源码全解析,全彩版附代码分享

摘要 MyBatis是一款优秀的持久层框架&#xff0c;它支持自定义SQL&#xff0c;存储过程以及高级映射&#xff0c;越来越多的企业已经将MyBatis使用到了正式的生产环境&#xff0c;而国内Mybatis流行的原因就在于绝大部分项目都是面向表结构编程的&#xff0c;把Java对象仅当成…

【敏捷研发系列】前端DevOps流水线实践

一、背景现状 软件开发从传统的瀑布流方式到敏捷开发&#xff0c;将软件交付过程中开发和测试形成快速的迭代交付&#xff0c;但在软件交付客户之前或者使用过程中&#xff0c;还包括集成、部署、运维等环节需要进一步优化交付效率。因此Devops的产生将敏捷的相关理念扩展到运…

认识操作系统

操作系统 1 OS 简史 1.1 批处理操作系统 1946-02-04 世界上第一台公认的通用计算机ENIAC在 宾夕法尼亚大学 诞生。1956 年实现 GM-NAA I/O 系统具备批处理特性。 1.2 从专用走向通用 1964 年&#xff0c;美国IBM公司发布 IBM System/360 的大型机。将计算机架构和实现分开…

【Java入门基础第10天】Java常用的转义字符

Java常用的转义字符1、\t:一个制表位,实现对齐功能2、\n:换行符3、\\:转义字符 一个4、\":一个"5、\:一个6、\r:一个回车 System.out.println("学刑法\r有钱途")7、应用实例(Exercise&#xff09;1、\t:一个制表位,实现对齐功能 \t:一个制表位,实现对齐功…

从文科生到前端专家 - 在转行时我想过的问题

▐ 在学习编程之前 在高中时&#xff0c;因为学不会物理和化学&#xff0c;我选择了文科&#xff0c;这也意味着计算机专业类对我关上了大门&#xff0c;不过在当时我也没有想到自己在未来会喜欢上写代码并以此为生。 现在回想起来&#xff0c;与编程有关的只有两件事情。 一是…

java学习day65(乐友商城)实现搜索、分页、排序

1.索引库数据导入 昨天我们学习了Elasticsearch的基本应用。今天就学以致用&#xff0c;搭建搜索微服务&#xff0c;实现搜索功能。 1.1.创建搜索服务 创建module&#xff1a; Pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <…

【软件测试】瓶颈?资深测试聊测试开发的瓶颈在哪?

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试开发的发展是不…

嵌入式C语言面向对象编程 --- 封装

大部分使用 C 语言进行开发的工程师,在接触更高级的编程语言之前,都认为 C 语言是面向过程的。事实也是如此,对于一些小规模的单片机应用程序,一般都是使用“面向过程”的思维进行单片机C语言编程开发。 但是,如果是需要用C语言开发一些规模比较大的软件的时候,比如操作…

pycharm 中sqlite升级方法

sqlite 3.21升级到3.40 Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> help Type help()…

小哥用Python兼职月入过万,用Python做项目有多赚钱?

问&#xff1a;请问用Python可以接哪些兼职的活赚钱&#xff1f; 1 兼职费用足够学费生活费 恰巧上学期间接过一些外包&#xff0c;恩&#xff0c;足够我和我媳妇的学费以及生活费&#xff0c;以及xx各种费用。 主要干过以下几种&#xff1a; 游戏外挂&#xff1a;主要开发…