我采用了这里的解决方法,将本地图片转为Base64格式,因此上面代码let imgUrl = “...”
的引号中是一段Base64编码。以下其他代码同。)
图像的棕褐色版本如何?
mounted(){
var canvas = new fabric.Canvas("canvas",{backgroundColor:'#ddd'})
let imgUrl = "..."
fabric.Image.fromURL(imgUrl,(img)=>{
img.filters.push(new fabric.Image.filters.Sepia());
img.applyFilters();
canvas.add(img);
由于“filters”属性是一个简单的数组,因此我们可以用通常的方式对其执行任何所需的操作-删除过滤器(通过pop
,splice
或shift
),添加过滤器(通过push
,splice
或unshift
),甚至组合多个过滤器。当我们调用applyFilters
时,“过滤器”数组中存在的所有过滤器都会被一一应用。因此,让我们尝试创建既棕褐色又明亮的图像。
mounted(){
var canvas = new fabric.Canvas("canvas",{backgroundColor:'#ddd'})
let imgUrl = "..."
fabric.Image.fromURL(imgUrl,(img)=>{
img.filters.push(
new fabric.Image.filters.Sepia(),
new fabric.Image.filters.Brightness({brightness:0.5})
img.applyFilters();
canvas.add(img);
请注意,我们还将{Brightness:100}
(官方教程是100,而我这里这里只给到了0.5,可能是图片原因又活着是其他,我给到1就全白了。)对象传递给了Brightness滤镜。这是因为可以应用某些过滤器而无需任何其他配置(例如,grayscale,invert,sepia),而其他过滤器可以对其行为进行更好的控制。对于亮度滤镜,它是实际的亮度级别(-1 全黑到1 全白)。对于噪声滤波器,它是噪声值(0-1000)。对于“去除颜色”滤镜,它是阈值和距离值。等等。
因此,既然您熟悉了Fabric过滤器,就该打破常规,创建自己的过滤器了!
用于创建过滤器的模板非常简单。我们需要创建一个“类”,然后定义applyTo
方法。 (可选)我们可以将filter赋予toJSON
方法(支持JSON序列化)和/或initialize
方法(支持可选参数)。
mounted(){
var canvas = new fabric.Canvas("canvas",{backgroundColor:'#ddd'})
let imgUrl = "...";
fabric.Image.filters.Redify = fabric.util.createClass(
fabric.Image.filters.BaseFilter,
type: "Redify",
* Fragment source for the redify program
fragmentSource:
"precision highp float;\n" +
"uniform sampler2D uTexture;\n" +
"varying vec2 vTexCoord;\n" +
"void main() {\n" +
"vec4 color = texture2D(uTexture, vTexCoord);\n" +
"color.g = 0.0;\n" +
"color.b = 0.0;\n" +
"gl_FragColor = color;\n" +
"}",
applyTo2d: function (options) {
var imageData = options.imageData,
data = imageData.data,
len = data.length;
for (i = 0; i < len; i += 4) {
data[i + 1] = 0;
data[i + 2] = 0;
fabric.Image.filters.Redify.fromObject =
fabric.Image.filters.BaseFilter.fromObject;
fabric.Image.fromURL(imgUrl, (img) => {
img.filters.push(new fabric.Image.filters.Redify());
img.applyFilters();
canvas.add(img);
在不花太多时间研究此代码的情况下,主要动作是循环循环。其中我们将每个像素的绿色(data [i + 1])和蓝色(data [i + 2])分量替换为0,从本质上将它们删除。标准rgb三元组的红色部分保持不变,基本上使整个图像都涂成红色。如您所见,正在向applyTo
方法传递一个选项对象,该对象包含在筛选管道阶段的图像的imageData。从那里,我们可以遍历其像素(getImageData().data
),以我们想要的任何方式对其进行修改。如果浏览器是启用WEBGL的过滤器,则可以在GPU上运行。为此,您必须提供一个片段着色器,以描述对像素执行的操作。构造中定义了许多过滤器,您可以在其中看到如何编写片段或顶点着色器的示例。
无论您是使用十六进制,RGB还是RGBA颜色更舒适,Fabric均可提供坚实的色彩基础,以帮助您最自然地表达自己。以下是在Fabric中定义颜色的一些方法:
new fabric.Color('#f55');
new fabric.Color('#123123');
new fabric.Color('356735');
new fabric.Color('rgb(100,0,100)');
new fabric.Color('rgba(10, 20, 30, 0.5)');
转换也很简单。 toHex()会将颜色实例转换为十六进制表示形式。 toRgb()—变为RGB one,toRgba()—变为具有alpha通道的RGB。
new fabric.Color('#f55').toRgb();
new fabric.Color('rgb(100,100,100)').toHex();
new fabric.Color('fff').toHex();
转换不是唯一可以使用颜色进行的操作。您还可以将一种颜色与另一种颜色叠加,或将其转换为灰度版本。
var redish = new fabric.Color('#f55');
var greenish = new fabric.Color('#5f5');
redish.overlayWith(greenish).toHex();
redish.toGrayscale().toHex();
使用颜色的一种更具表现力的方式是通过渐变。渐变使我们可以将一种颜色混合到另一种颜色,从而创建一些令人惊叹的图形效果。
Fabric支持在所有对象上设置填充或描边属性的渐变。为了为对象设置渐变,请首先创建渐变,然后将其分配给填充或描边。
<template>
<div class="test">
<canvas id="canvas"></canvas>
</template>
<script>
import {fabric} from "fabric"
export default {
data(){
return {
canvas:''
mounted(){
this.canvas = new fabric.Canvas("canvas",{
width:300,
height:300,
backgroundColor:"#ddd"
var circle = new fabric.Circle({
left:100,
top:100,
radius:50
var gradient = new fabric.Gradient({
type:"linear",
gradientUnits:"pixels",
coords:{x1:0,y1:0,x2:0,y2:circle.height},
colorStops:[
{offset:0,color:"#000",},
{offset:1,color:"#fff"}
circle.set("fill",gradient)
this.canvas.add(circle)
</script>
<style>
</style>
在上面的示例中,我们在100,100位置创建了一个半径为50px的圆。然后,我们将其填充设置为一个渐变,该渐变跨越该圆圈的整个高度,从黑色到白色。
渐变选项对象具有2个主要属性,coords和colorStops。coords
期望至少2个坐标对(x1,y1和x2,y2)将定义渐变在对象上的扩展方式,而colorStops
是定义渐变颜色的数组。数组中的每种颜色都由一个offset
定义,该偏移量表示其在渐变上的位置,该color
定义了颜色本身,并最终定义了opacity
属性。您可以定义任意多个色标,只要它们的偏移范围为0到1。 “ 0”代表渐变的开始,“ 1”代表渐变的结束。坐标是相对于对象左上角的,因此圆的最高点是0,最低点是circle.height
。
您可以指定类型为linear
或radial
以获得两种不同类型的渐变,而且gradientUnits
默认为像素,但可以指定为“百分比”。 “百分比”将允许以对象大小的百分比指定渐变大小,“ 1”是对象大小的100%。
此设置对fabric.Text
对象有用,该对象根据文本内容更改宽度或高度。
这是一个从左到右的红蓝色渐变的示例:
mounted(){
this.canvas = new fabric.Canvas("canvas",{
width:300,
height:300,
backgroundColor:"#ddd"
var circle = new fabric.Circle({
left:100,
top:100,
radius:50
var gradient1 = new fabric.Gradient({
type:"linear",
gradientUnits:"pixels",//or "pencentage"
coords:{x1:0,y1:0,x2:circle.height,y2:0},
colorStops:[
{offset:0,color:"red"},
{offset:1,color:"blue"}
// or in pencentage
// var gradient2 = new fabric.Gradient({
// type:"linear",
// gradientUnits:"percentage",
// coords:{x1:0,y1:0,x2:1,y2:0},
// colorStops:[
// {offset:0,color:'red'},
// {offset:1,color:"blue"}
// ]
// })
circle.set("fill",gradient1)
this.canvas.add(circle)
这是一个5级彩虹渐变,颜色的间隔甚至为20%:
mounted(){
this.canvas = new fabric.Canvas(“canvas”,{
width:300,
height:300,
backgroundColor:"#ddd"
})
var circle = new fabric.Circle({
left:100,
top:100,
radius:50
var gradient3 = new fabric.Gradient({
type:"linear",
gradientUnits:"pixels",
coords:{x1:0,y1:0,x2:circle.height,y2:0},
colorStops:[
{offset:0,color:'red'},
{offset:0.2,color:'orange'},
{offset:0.4,color:'yellow'},
{offset:0.6,color:"green"},
{offset:0.8,color:'blue'},
{offset:1,color:"purple"}
circle.set("fill",gradient3)
this.canvas.add(circle)
如果您不仅想在画布上显示图像和矢量形状,还想显示文本怎么办?Fabric都为你做好了!遇到fabric.Text
对象。
我们在Fabric中提供文本抽象有两个原因。首先,允许以面向对象的方式处理文本。原生canvas方法-像往常一样-只允许进行低级别的填充或笔划文本。通过实例化fabric.Text
例如,我们可以像处理任何其他Fabric object一样处理文本—移动它、缩放它、更改它的属性等等。
第二个原因是要提供比canvas所提供的功能更丰富的功能。某些Fabric附加功能包括:
- Multiline support 不幸的是,原生文本方法只是忽略了新行。
- Text alignment Left, center, right. 使用多行文字时非常有用。
- Text background 背景也遵循文本对齐。
- Text decoration Underline, overline, strike-through.
- Line height 使用多行文字时出错。
- Char spacing 使文本更紧凑或间距更大。
- Subranges 将颜色和属性应用于文本对象的子范围。
- Multibyte 支持表情!
- On canvas editing 使用交互式类,您可以直接在canvas上键入文本。
hello word的例子怎么样?
var text = new fabric.Text('hello world', { left: 100, top: 100 });
canvas.add(text);
这是正确的!在画布上显示文本就像在所需位置添加fabric.Text
实例一样简单。如您所见,唯一需要的第一个参数是实际的文本字符串。第二个参数是通常的选项对象,可以具有任何通常的left,top,fill,opacity等属性。
但是,当然,文本对象也具有其自己的,独特的,与文本相关的属性。让我们看看其中的一些:
默认情况下设置为“ Times New Roman”,此属性允许我们更改用于渲染文本对象的字体系列。更改它会立即使文本以新字体呈现。
字体粗细允许使文本看起来更粗或更细。就像在CSS中一样,您可以使用关键字(“ normal”,“ bold”)或数字(100、200、400、600、800)。请注意,是否可以使用特定的粗细取决于所选字体的粗细可用性。如果您使用的是远程字体,则需要确保同时提供普通和粗体(以及任何其他必需的粗细)字体定义。
<template>
<div class="text">
<canvas id="canvas"></canvas>
</template>
<script>
import {fabric} from "fabric"
export default {
data(){
return {
canvas:''
mounted(){
this.canvas =new fabric.Canvas("canvas",{
width:400,
height:300,
backgroundColor:'#ddd'
var text = new fabric.Text("hello world",{
top:5
var comicSansText = new fabric.Text("I am in Comic Sans",{
fontFamily:"Comic Sans",
top:45
var text40 = new fabric.Text("I am at fontsize 40",{
fontSize:40,
top:105
var text20 = new fabric.Text("I am at fontSize 20",{
fontSize:20,
top:145
var normalText = new fabric.Text("I am a normal text",{
fontWeight:"normal",
top:185
var boldText = new fabric.Text("I am at bold text",{
fontWeight:"bold",
top:225
this.canvas.add(text,comicSansText,text40,text20,normalText,boldText)
</script>
<style>
</style>
文本修饰允许在文本上添加非轮廓,上划线或删除线。这与CSS相似,但是Fabric更进一步,并允许将以上内容的任何组合一起使用。因此,您可以同时使用带下划线和上划线,或带下划线和删除线的文本。
在1.3.0版之前,此属性称为“ textShadow” 。
文字阴影由4个成分组成:颜色,水平偏移,垂直偏移和模糊大小。如果您使用过CSS中的阴影,这可能看起来非常熟悉。通过更改这些值,可以进行很多组合。
mounted(){
this.canvas =new fabric.Canvas("canvas",{
width:400,
height:400,
backgroundColor:'#ddd'
var underlineText = new fabric.Text("I am an undrline text",{
underline:true,
top:5
var strokeThroughText = new fabric.Text("I am a stroke-through text",{
linethrough:true,
top:65
var overlineText = new fabric.Text("I am overline text",{
overline:true,
top:125
var shadowText1 = new fabric.Text("I am a text with shadow",{
shadow:"rgba(0,0,0,0.3) 5px 5px 5px",
top:185
var shadowText2 = new fabric.Text("And another shadow",{
shadow:"rgba(0,0,0,0.2) 0 0 5px",
top:245
var shadowText3 = new fabric.Text("Lorem ipsum dolor sit",{
shadow:"green -5px -5px 3px",
top:305
this.canvas.add(underlineText,strokeThroughText,overlineText,shadowText1,shadowText2,shadowText3)
字体样式可以是2个值之一:normal或italic。这类似于同名的CSS属性。
通过组合笔触(笔触的颜色)和strokeWidth(其宽度),可以对文本实现一些有趣的效果。
使用多行文本时,文本对齐很有用。对于单行文本,边框的宽度始终与该行的宽度完全匹配,因此没有任何对齐的地方。
允许的值为“ left”,“ center”和“ right”。
mounted(){
this.canvas =new fabric.Canvas("canvas",{
width:500,
height:400,
backgroundColor:'#ddd'
var italicText = new fabric.Text("A very fancy italic text",{
fontStyle:'italic',
fontFamily:"Delicious",
top:5
var anotherItalicText = new fabric.Text("another italic text",{
fontStyle:"italic",
fontFamily:"Hoefler Text",
top:65
var textWithStroke = new fabric.Text("Text with a stroke",{
stroke:"#ff1318",
strokeWidth:1,
top:145
var loremIpsumDolor = new fabric.Text("Lorem ipsum dolor",{
fontFamily:"Impact",
stroke:"#c3bfbf",
strokeWidth:3,
top:205
var text = "this is\na mutiline\nnext\naligned right!";
var alignedRightText = new fabric.Text(text,{
textAlign:"right",
top:285
this.canvas.add(italicText,anotherItalicText,textWithStroke,loremIpsumDolor,alignedRightText)
CSS领域可能熟悉的另一个属性是lineHeight。它允许我们更改多行文本中文本行之间的垂直间距。在下面的示例中,第一个文本块的lineHeight为3,第二个文本为— 1。
最后,textBackgroundColor可以为文本提供背景。请注意,背景仅填充文本字符占用的空间,而不填充整个边界框。这意味着文本对齐方式会更改文本背景的呈现方式。线高也是如此,因为背景尊重线之间的垂直空间,由lineHeight创建。
mounted(){
this.canvas =new fabric.Canvas("canvas",{
width:600,
height:1000,
backgroundColor:'#ddd'
var text2 = "Lorem ipsum dolor sit amet,\nconsectetur adipisicing elit,\nsed do eiusmod tempor incididunt\nut labo"
var lineHeight2 = new fabric.Text(text2,{
lineHeight:2,
top:5
var lineHeight1 = new fabric.Text(text2,{
lineHeight:1,
top:345
var text3 = "this is\na multiline\ntext\nwith\ncustom lineheight\n& backgound!"
var textWithBackground = new fabric.Text(text3,{
textBackgroundColor:"rgb(0,200,0)",
top:565
this.canvas.add(lineHeight2,lineHeight1,textWithBackground)
事件驱动的体系结构是框架内强大功能和灵活性的基础。 Fabric也不例外,它提供了一个广泛的事件系统,从低级的“鼠标”事件到高级的对象事件。
这些事件使我们能够利用画布上发生的各种动作的不同时刻。是否想知道何时按下鼠标?只需观察“ mouse:down”事件即可。将对象添加到画布的时间怎么样? “object:added”在那里为您服务。那么当整个画布重新渲染时又如何呢?只需使用“ after:render”。
事件API非常简单,类似于jQuery,Underscore.js或其他流行的JS库。有on
方法可以初始化事件监听器,而off
方法可以将其删除。
让我们看一个实际的例子:
<template>
<div class="event">
<canvas id="canvas"></canvas>
</template>
<script>
import { fabric } from "fabric";
export default {
mounted() {
var canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
canvas.on("mouse:down", (options) => {
console.log(options.e.clientX, options.e.clientY);
</script>
<style>
</style>
我们将事件“ mouse:down”事件侦听器添加到画布上,并为其提供事件处理程序,该事件处理程序将记录事件起源的坐标。换句话说,它将记录鼠标在画布上的确切位置。事件处理程序接收一个options对象,该对象具有2个属性:e-原始事件,target-画布上单击的对象(如果有)。该事件始终存在,但仅当您确实单击画布上的某个对象时,目标才存在。目标也仅传递给有意义的事件处理程序。例如,对于“ mouse:down”而不是“ after:render”(表示重新绘制了整个画布)。
mounted() {
var canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var rect = new fabric.Rect({
width:100,
height:50,
fill:"green"
rect.on("selected",()=>{
console.log('selected a rectangle');
canvas.on("mouse:down", (options) => {
console.log(options.e.clientX, options.e.clientY);
if (options.target) {
console.log("an object was clicked!", options.target.type);
});
canvas.add(rect)
上面的示例将记录“单击了一个对象!”如果单击一个对象。它还将显示单击的对象的类型。
那么Fabric中还有哪些其他事件可用?好吧,在鼠标级别的菜单中有“ mouse:down”,“ mouse:move”和“ mouse:up”。从通用的开始,有“ after:render”。然后是与选择相关的事件:“before:selection:cleared”,“selection:created”,“selection:cleared”。最后,对象是:“object:modified”,“object:selected”,“object:moving”,“object:scaling”,“object:rotating”,“object:added”和“object:removed”
请注意,每次移动(或缩放)一个对象(甚至移动一个像素)时,都会连续触发“ object:moving”(或“ object:scaling”)之类的事件。另一方面,仅在操作(对象修改或选择创建)结束时才触发“ object:modified”或“ selection:created”之类的事件。
注意我们如何将事件直接附加到画布上(canvas.on('mouse:down',...)
)。可以想象,这意味着事件都限于画布实例。如果页面上有多个画布,则可以将不同的事件侦听器附加到每个侦听器。它们都是独立的,并且仅尊重分配给他们的事件。
为了方便起见,Fabric进一步扩展了事件系统,并允许您将侦听器直接附加到画布对象。让我们来看看:
mounted() {
var canvas = new fabric.Canvas("canvas", {
width: 300,
height: 300,
backgroundColor: "#ddd",
});
var rect = new fabric.Rect({
width:100,
height:50,
fill:"green"
rect.on("selected",()=>{
console.log('selected a rectangle');
var circle = new fabric.Circle({
radius:75,
fill:"blue",
top:100,
left:100
circle.on("selected",()=>{
console.log("selected a circle");
canvas.add(rect,circle)
我们将事件侦听器直接附加到矩形和圆形实例。代替“ object:selected”,我们使用“ selected”事件。同样,我们可以使用“ modified”事件(附加到画布上时为“ object:modified”),“ rotating”事件(附加到画布上时为“ object:rotating”),依此类推。
查看此events demo ,以对Fabric的事件系统进行更广泛的探索。
阅读 Part 3/第三部分.
点击点在canvas中的位置
点击点在页面中的位置
点击点在对象中的位置
Introduction to Fabric.js. Part 2在本系列的第一部分中,我们只是开始熟悉Fabric.js。我们研究了使用Fabric的原因,对象模型和对象层次结构,Fabric中可用的不同种类的实体-简单的形状,图像和复杂的路径。我们还学习了如何对画布上的Fabric对象执行简单的操作。既然大多数基本知识都结束了,那么让我们开始一些有趣的事情吧!Animation没有动画工具的canvas库是不会受人尊重的。而且Fabric也不例外。由于具有如此强大的对象模型和图形功能,因此如果没