当前位置:网站首页>Fabric.js 更换图片的3种方法(包括更换分组内的图片,以及存在缓存的情况)
Fabric.js 更换图片的3种方法(包括更换分组内的图片,以及存在缓存的情况)
2022-07-02 05:08:00 【德育处主任】
本文简介
我列举了3种在 Fabric.js
中 更换图片 的方法。
其中还包括 更换组内图片 的操作。
<br>
<br>
环境和版本
Chrome浏览器版本:96.0.4664.45
Fabric.js版本:4.6.0
我是在原生环境下开发的,同时也提供了一份 Vue3
环境下开发的代码(文末有链接)。
<br>
<br>
动手操作
接下来有3个案例,使用了2张图片 Agumon.png
和 Bhikkhu.png
,图片是在 iconfont 网站上找到的。
如果需要使用本案例的图片,可以在文末提供的仓库中获取。
情景1:更换图片元素的src
如果在画布上添加的是 Image
对象,那么可以使用 Image.setSrc
设置新的图片,然后再使用 Canvas.renderAll
刷新一下画布即可。
<style> canvas { border: 1px solid #ccc; }</style><button onclick="change()">修改图片</button><canvas width="300" height="300" id="canvas"></canvas><script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script><script> // 实例化canvas canvas = new fabric.Canvas('canvas') // 创建图片对象 fabric.Image.fromURL('../../images/Agumon.png', oImg => { // 将图片对象添加到 canvas 中 canvas.add(oImg) }) // 更换图片事件 function change() { // 获取图片对象。因为在本例中,画布里只有一个元素,用 getObjects() 获取到的数组第一个元素就是图片咯 const img = canvas.getObjects()[0] // 使用 setSrc 方法更改图片,第二个参数是回调函数,在回调函数里刷新一下 canvas 即可 img.setSrc('../../images/Bhikkhu.png', () => { canvas.renderAll() }) }</script>
上面这种情景是最简单的。
如果画布上有多个图形和图片,你可能需要在创建图片的时候加一些自定义属性进去判断。
使用 fabric.getObjects().find()
去搜索就行了。
find()
就是数组的原始方法。
<br>
<br>
情景2:修改组内的图片(无缓存)
创建组默认是有缓存的,有缓存的话使用 Canvas.renderAll()
方法重新渲染也不会更新图片。
所以在创建组的时候要声明 不缓存: Group.objectCaching
。
<style> canvas { border: 1px solid #ccc; }</style><button onclick="change()">修改图片</button><canvas width="300" height="300" id="canvas"></canvas><script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script><script> // 实例化canvas canvas = new fabric.Canvas('canvas') // 创建图片对象 fabric.Image.fromURL('../../images/Agumon.png', oImg => { // 文本 const text = new fabric.Text('没缓存的组', { fontSize: 14, top: 50 }) // 创建组 const group = new fabric.Group([oImg, text], { objectCaching: false // 不缓存!!! }) // 将分组添加到canvas里 canvas.add(group) }) // 更换图片事件 function change() { // 获取组 const group = canvas.getObjects()[0] // 获取图片 const img = group.getObjects().find(item => { // 通过 isType 判断图片元素,因为组内有2个元素(一个图片,一个文本) return item.isType('image') }) // 找到图片,然后更换 img.setSrc('../../images/Bhikkhu.png', () => { // 更换完图片,刷新一下 canvas canvas.renderAll() }) }</script>
这种情景,重点在创建组时,要声明 objectCaching: false
。
<br>
<br>
情景3:修改组内的图片(有缓存)
如果 组(Group) 设置了缓存,又需要更换 组(Group) 内的图片。
我的做法是:
- 查找图片对象,并保存到一个变量上;
- 删除分组内的图片对象(使用
Group.removeWithUpdate
); - 更新图片对象的
src
指向(使用Image.setSrc
); - 将图片放到分组里(使用
Group.addWithUpdate
); - 重新渲染画布(使用
Canvas.renderAll
);
<br>
<style> canvas { border: 1px solid #ccc; }</style><button onclick="change()">修改图片</button><canvas width="300" height="300" id="canvas"></canvas><script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.min.js"></script><script> // 实例化canvas canvas = new fabric.Canvas('canvas') // 创建图片对象 fabric.Image.fromURL('../../images/Agumon.png', oImg => { // 文本 const text = new fabric.Text('没缓存的组', { fontSize: 14, top: 50 }) // 创建组 const group = new fabric.Group([oImg, text]) // 将分组添加到canvas里 canvas.add(group) }) // 更换图片事件 function change() { // 获取组 const group = canvas.getObjects()[0] // 【1】查找图片对象,并保存到一个变量上 const img = group.getObjects().find(item => { // 通过 isType 判断图片元素,因为组内有2个元素(一个图片,一个文本) return item.isType('image') }) // 【2】删除分组内的图片对象 group.removeWithUpdate(img) // 【3】更新图片对象的 `src` 指向 img.setSrc('../../images/Bhikkhu.png', () => { // 【4】将图片放到分组里 group.addWithUpdate(img) // 【5】重新渲染画布 canvas.renderAll() }) }</script>
按这个例子的方式是可以达到目的的,但总觉得不太舒服。
如果你有更好的思路可以分享一下,一起讨论学习。
<br>
如果你的项目中也需要更改图片,但又不在以上3种情景中,可以留言,我会尝试解决。
<br>
<br>
代码仓库
<br>
<br>
更多推荐
《Fabric.js实现渐变(Gradient)效果,包括径向渐变radial》
点赞 + 关注 + 收藏 = 学会了
边栏推荐
- Global and Chinese market of cell culture freezers 2022-2028: Research Report on technology, participants, trends, market size and share
- 培养中小学生对教育机器人的热爱之心
- Change deepin to Alibaba image source
- Application d'un robot intelligent dans le domaine de l'agroécologie
- 国产全中文-自动化测试软件Apifox
- [opencv] image binarization
- Ansible installation and use
- Pytest learning ----- pytest Interface Association framework encapsulation of interface automation testing
- LeetCode 241. Design priorities for operational expressions (divide and conquer / mnemonic recursion / dynamic programming)
- Learn BeanShell before you dare to say you know JMeter
猜你喜欢
Line by line explanation of yolox source code of anchor free series network (7) -- obj in head_ loss、Cls_ Loss and reg_ Calculation and reverse transmission of loss I
关于Steam 教育的知识整理
Lay the foundation for children's programming to become a basic discipline
Latest: the list of universities and disciplines for the second round of "double first-class" construction was announced
el form 表单validate成功后没有执行逻辑
Rhcsa --- work on the fourth day
Rhcsa --- work on the third day
Getting started with pytest -- description of fixture parameters
農業生態領域智能機器人的應用
LM09丨费雪逆变换反转网格策略
随机推荐
Implementation of leetcode two number addition go
Go GC garbage collection notes (three color mark)
Line by line explanation of yolox source code of anchor free series network (7) -- obj in head_ loss、Cls_ Loss and reg_ Calculation and reverse transmission of loss I
Pyflink writes MySQL examples with JDBC
Mathematical problems (number theory) trial division to judge prime numbers, decompose prime factors, and screen prime numbers
Getting started with pytest -- description of fixture parameters
Feign realizes file uploading and downloading
Pytest learning ----- pytest Interface Association framework encapsulation of interface automation testing
培养中小学生对教育机器人的热爱之心
从数组中找出和为目标的下标
2022 Alibaba global mathematics competition, question 4, huhushengwei (blind box problem, truck problem) solution ideas
LeetCode 1175. Prime number arrangement (prime number judgment + Combinatorial Mathematics)
C# 图片显示占用问题
國產全中文-自動化測試軟件Apifox
National all Chinese Automatic Test Software apifox
Save the CDA from the disc to the computer
黑马笔记---Map集合体系
Use of typescript classes
The reason why sizeof (ARR) / sizeof (arr[0]) is used in the function to calculate the length of the array is incorrect
Pycharm breakpoint management: temporarily cancel some breakpoints + run directly to a line