来源:未知 时间:2022-07-04 00:16 作者:小飞侠 阅读:次
[导读] Fabric.js 简介。 第2部分。 在 本系列的第一部分 ,我们才刚刚开始熟悉 Fabric.js。 我们研究了使用 Fabric 的原因,它的对象模型和对象层次结构,以及 Fabric 中可用的不同类型的实体——...
Fabric.js 简介。第2部分。在本系列的第一部分,我们才刚刚开始熟悉 Fabric.js。我们研究了使用 Fabric 的原因,它的对象模型和对象层次结构,以及 Fabric 中可用的不同类型的实体——简单的形状、图像和复杂的路径。我们还学习了如何在画布上使用 Fabric 对象执行简单的操作。 既然大部分基础知识都已经过去了,让我们开始做一些有趣的事情吧! 动画没有一个受人尊敬的画布库没有动画设施。Fabric 也不例外。由于有如此强大的对象模型和图形功能,如果没有内置动画助手将是一种耻辱。 还记得改变任何对象的属性是多么容易吗?我们只是调用了 rect.set('angle', 45); 好吧,动画对象同样容易。每个 Fabric 对象都有 rect.animate('angle', 45, { onChange: canvas.renderAll.bind(canvas) }); 第一个参数是动画的属性。第二个参数是动画的结束值。如果矩形有 -15° 角,并且我们传递 45,它将从 -15° 动画到 45°。第三个参数是一个可选对象,指定动画的更精细细节——持续时间、回调、缓动等。 一个方便的特性 rect.animate('left', '+=100', { onChange: canvas.renderAll.bind(canvas) }); 类似地,将物体逆时针旋转 5 度,可以这样完成: rect.animate('angle', '-=5', { onChange: canvas.renderAll.bind(canvas) }); 你可能想知道为什么我们总是在那里指定“onChange”回调。第三个参数不是可选的吗?是的,但是调用 请记住,在该画布表面下方有整个对象模型。对象有自己的属性和关系,canvas只负责将它们的存在投射到外界。
那么我们可以传递哪些其他选项来制作动画呢?
所有这些选项都应该是不言自明的,除了可能放宽一个。让我们仔细看看。 默认情况下, rect.animate('left', 500, { onChange: canvas.renderAll.bind(canvas), duration: 1000, easing: fabric.util.ease.easeOutBounce }); 注意 所以这几乎涵盖了Fabric的动画部分。只是为了给您一些可能的想法-您可以为对象的角度设置动画以使其旋转;为左/上属性设置动画以使其移动;为宽度/高度设置动画以使其缩小/增长;动画不透明度以使其淡入/淡出;等等。 fabric.runningAnimations如果您需要访问当前由 fabric 运行的动画,请使用 方便的方法:
let cancel = fabric.util.animate({...}); let i = fabric.runningAnimations.findAnimationIndex(cancel); let context = fabric.runningAnimations.findAnimation(cancel); let cancelled = fabric.runningAnimations.cancelAll(); // the following statements are true cancelled[i] === context; cancelled[i].cancel === cancel; fabric.runningAnimations.length === 0; 图像过滤器在本系列的第一部分,我们学习了如何在 Fabric 中处理图像。有 但是,尽管处理图像很有趣,但对它们应用图像过滤器会更酷! 默认情况下,Fabric 提供了很少的过滤器,无论是针对启用 WEBGL 的浏览器还是不支持的浏览器。它还可以轻松定义自己的。一些您可能非常熟悉的内置过滤器 - 过滤器以去除白色背景、灰度过滤器、反转或亮度过滤器。其他的可能不太受欢迎——彩色矩阵、棕褐色或噪声。 那么我们如何对 Fabric 中的图像应用过滤器呢?好吧,每个实例 所以让我们创建一个灰度图像。 fabric.Image.fromURL('pug.jpg', function(img) { // 添加滤镜 img.filters.push(new fabric.Image.filters.Grayscale()); // 应用滤镜并在完成后重新渲染画布 img.applyFilters(); // 将图像添加到画布上(它也会重新渲染画布) canvas.add(img); }); 棕褐色版本的图像怎么样? fabric.Image.fromURL('pug.jpg', function(img) { img.filters.push(new fabric.Image.filters.Sepia()); img.applyFilters(); // 将图像添加到画布上(它也重新渲染画布) canvas.add(img); }); 由于“filters”属性是一个简单的数组,我们可以用它以通常的方式执行任何所需的操作——删除过滤器(通过 fabric.Image.fromURL('pug.jpg', function(img) { img.filters.push( new fabric.Image.filters.Sepia(), new fabric.Image.filters.Brightness({亮度: 100 })) ; img.applyFilters(); canvas.add(img); }); 请注意,我们还将 现在您已经熟悉了 Fabric 过滤器,是时候打破常规,创建自己的过滤器了! 创建过滤器的模板非常简单。我们需要创建一个“类”,然后定义 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, i, 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; 无需过多研究此代码,主要操作就在循环中发生。我们用 0 替换每个像素的绿色 (data[i+1]) 和蓝色 (data[i+2]) 分量,基本上将它们删除。标准 rgb 三元组的红色分量保持不变,基本上使整个图像涂成红色。如您所见, 颜色无论您更喜欢使用 hex、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)'); 转换也很简单。 new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)" new fabric.Color('rgb(100,100,100)').toHex(); // "646464" new fabric.Color('fff').toHex(); // "FFFFFF" 转换并不是您可以对颜色进行的唯一操作。您还可以将一种颜色与另一种颜色叠加,或将其转换为灰度版本。 var redish = new fabric.Color('#f55'); var greenish = new fabric.Color('#5f5'); redish.overlayWith(greenish).toHex(); // "AAAA55" redish.toGrayscale().toHex(); // "A1A1A1" 渐变使用颜色的一种更具表现力的方式是通过渐变。渐变让我们可以将一种颜色混合到另一种颜色中,创造出一些令人惊叹的图形效果。 Fabric 支持渐变设置所有对象的填充或描边属性。为了给对象设置渐变,首先创建渐变,然后将其分配给填充或描边。 var circle = new fabric.Circle({ left: 100, top: 100, radius: 50 }); var gradient = new fabric.Gradient({ type: 'linear', gradientUnits: 'pixels', // or 'percentage' coords: { x1: 0, y1: 0, x2: 0, y2: circle.height }, colorStops:[ { offset: 0, color: '#000' }, { offset: 1, color: '#fff'} ] }) circle.set('fill', gradient); 在上面的示例中,我们在 100,100 位置创建了一个圆,半径为 50px。然后,我们将其填充设置为跨越该圆圈整个高度的渐变,从黑色到白色。 渐变选项对象有 2 个主要属性,坐标和颜色停止。 这是一个从左到右的红蓝渐变示例: var gradient = new fabric.Gradient({ type: 'linear', gradientUnits: 'pixels', // or 'percentage' coords: { x1: 0, y1: 0, x2: circle.width, y2: 0 }, colorStops:[ { offset: 0, color: 'red' }, { offset: 1, color: 'blue'} ] }) // or in percentage var gradient = 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'} ] }) 这是一个 5 档的彩虹渐变,颜色以 20% 的间隔跨越: var gradient = new fabric.Gradient({ type: 'linear', gradientUnits: 'pixels', // or 'percentage' coords: { x1: 0, y1: 0, x2: circle.width, 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' } ] }); 文本如果您不仅想在画布上显示图像和矢量形状,还想显示文本怎么办?面料有你!遇见 我们在 Fabric 中提供文本抽象有两个原因。首先,是允许以面向对象的方式处理文本。像往常一样,本机画布方法只允许在非常低的级别上填充或描边文本。通过实例化 第二个原因是提供比 canvas 给我们的功能更丰富的功能。一些织物添加包括:
你好世界的例子怎么样? var text = new fabric.Text('hello world', { left: 100, top: 100 }); canvas.add(文本); 这是正确的! 当然,文本对象也有自己独特的与文本相关的属性。让我们看看其中的一些: 字体系列默认设置为“Times New Roman”,此属性允许我们更改用于渲染文本对象的字体系列。更改它会立即使文本以新字体呈现。 var comicSansText = new fabric.Text("我在 Comic Sans", { fontFamily: 'Comic Sans' }); 字体大小字体大小控制渲染文本的大小。请注意,与 Fabric 中的其他对象不同,您不能直接更改文本的宽度/高度属性。相反,您需要更改“fontSize”值以使文本对象更大或更小。要么,要么你总是可以使用 scaleX/scaleY 属性。 var text40 = new fabric.Text("我在 fontSize 40", { fontSize: 40 }); var text20 = new fabric.Text("我在 fontSize 20", { fontSize: 20 }); 字体重量字体粗细允许使文本看起来更厚或更薄。就像在 CSS 中一样,您可以使用关键字(“normal”、“bold”)或数字(100、200、400、600、800)。请注意,您是否可以使用某些粗细取决于所选字体的该粗细的可用性。如果您使用远程字体,则需要确保提供正常和粗体(以及任何其他所需的粗细)字体定义。 var normalText = new fabric.Text("我是普通文本", { fontWeight: 'normal' }); var boldText = new fabric.Text("我是粗体", { fontWeight: 'bold' }); 文字装饰文本装饰允许在文本中添加下划线、上划线或删除线。这与 CSS 类似,但 Fabric 更进一步,允许将上述任意组合一起使用。所以你可以有一个既是下划线又是上划线的文本,或者是下划线和删除线,等等。 var underlineText = new fabric.Text("我是下划线文本", { underline; true }); var strokeThroughText = new fabric.Text("我是描边文本", { linethrough: true }); var overlineText = new fabric.Text("我是一个上划线文本", { overline: true }); 阴影此属性在 1.3.0 版之前称为“textShadow” 文本阴影由 4 个组件组成:颜色、水平偏移、垂直偏移和模糊大小。如果您在 CSS 中使用过阴影,这可能看起来很熟悉。通过更改这些值可以实现许多组合。 var shadowText1 = new fabric.Text("我是带阴影的文本", { shadow: 'rgba(0,0,0,0.3) 5px 5px 5px' }); var shadowText2 = new fabric.Text("还有另一个阴影", { shadow: 'rgba(0,0,0,0.2) 0 0 5px' }); var shadowText3 = new fabric.Text("Lorem ipsum dolor sit", { shadow: 'green -5px -5px 3px' }); 字体样式字体样式可以是 2 个值之一:正常或斜体。这类似于同名 CSS 属性。 var italicText = new fabric.Text("一个非常漂亮的斜体文本", { fontStyle: 'italic', fontFamily: 'Delicious' }); var anotherItalicText = new fabric.Text("另一个斜体文本", { fontStyle: 'italic', fontFamily: 'Hoefler Text' }); 行程和行程宽度通过组合 stroke(笔触的颜色)和 strokeWidth(它的宽度),你可以在你的文本上实现一些有趣的效果。这里有几个例子: var textWithStroke = new fabric.Text("带有笔画的文本", { stroke: '#ff1318', strokeWidth: 1 }); var loremIpsumDolor = new fabric.Text("Lorem ipsum dolor", { fontFamily: 'Impact', stroke: '#c3bfbf', strokeWidth: 3 }); 文本对齐处理多行文本时,文本对齐非常有用。对于单行文本,边界框的宽度始终与该行的宽度完全匹配,因此无需对齐。 允许的值为“left”、“center”和“right”。 var text = '这是\n多行\n文本\n右对齐!'; var alignedRightText = new fabric.Text(text, { textAlign: 'right' }); 线高CSS 领域可能熟悉的另一个属性是 lineHeight。它允许我们更改多行文本中文本行之间的垂直间距。在以下示例中,第一个文本块的 lineHeight 为 3,第二个文本块的 lineHeight 为 1。 var lineHeight3 = new fabric.Text('Lorem ipsum ...', { lineHeight: 3 }); var lineHeight1 = new fabric.Text('Lorem ipsum ...', { lineHeight: 1 }); 文字背景颜色最后, textBackgroundColor 允许为文本提供背景。请注意,背景仅填充文本字符占用的空间,而不是整个边界框。这意味着文本对齐会改变文本背景的呈现方式。行高也是如此,因为背景尊重行之间的垂直空间,由 lineHeight 创建。 var text = '这是\n 多行\ntext\nwith\ncustom lineheight\n&background'; var textWithBackground = new fabric.Text(text, { textBackgroundColor: 'rgb(0,200,0)' }); 活动事件驱动架构是框架内一些惊人的功能和灵活性的基础。Fabric 也不例外,它提供了一个广泛的事件系统,从低级“鼠标”事件到高级对象事件。 这些事件使我们能够利用画布上发生的各种动作的不同时刻。想知道鼠标何时被按下?只需观察“鼠标:按下”事件。什么时候将对象添加到画布上?“对象:添加”是给你的。那么当整个画布重新渲染时呢?只需使用“之后:渲染”。 事件 API 非常简单,类似于 jQuery、Underscore.js 或其他流行的 JS 库。有 我们来看一个实际的例子: var canvas = new fabric.Canvas('...'); canvas.on('mouse:down', function(options) { console.log(options.e.clientX, options.e.clientY); }); 我们将事件“mouse:down”事件侦听器添加到画布上,并为其提供一个事件处理程序,该处理程序将记录事件起源的坐标。换句话说,它将记录鼠标在画布上的确切位置。事件处理程序接收一个选项对象,该对象具有 2 个属性: canvas.on('mouse:down', function(options) { if (options.target) { console.log('an object was clicked!', options.target.type); } }); 上面的例子将记录“一个对象被点击了!” 如果您单击一个对象。它还将显示单击的对象的类型。 那么 Fabric 中还有哪些其他事件可用?好吧,从鼠标级别来看,有“ mouse:down ”、“ mouse:move ”和“ mouse:up ”。从通用的,有“ after:render ”。然后是与选择相关的事件:“ before:selection:cleared ”、“ selection:created ”、“ selection:cleared ”。最后,对象:“对象:修改”,“对象:选定”,“对象:移动”,“对象:缩放”,“对象:旋转”,“对象:添加”, 请注意,每次移动(或缩放)对象甚至移动一个像素时,都会连续触发诸如“object:moving”(或“object:scaling”)之类的事件。另一方面,像“object:modified”或“selection:created”这样的事件仅在动作结束时触发(对象修改或选择创建)。 请注意我们是如何将事件直接附加到画布 ( 为方便起见,Fabric 进一步改进了事件系统,并允许您将侦听器直接附加到画布对象。让我们来看看: var rect = new fabric.Rect({ width: 100, height: 50, fill: 'green' }); rect.on('selected', function() { console.log('selected a rectangle'); }); var circle = new fabric.Circle({ radius: 75, fill: 'blue' }); circle.on('selected', function() { console.log('selected a circle'); }); 我们将事件侦听器直接附加到矩形和圆形实例。我们使用的是“selected”事件,而不是“object:selected”。类似地,我们可以使用“修改”事件(附加到画布时为“object:modified”)、“旋转”事件(附加到画布时为“object:rotating”)等等。 查看此事件演示以更广泛地探索 Fabric 的事件系统。 阅读第 3 部分。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com