vue2+Fabric.js库的使用(4)--Fabric的对象/图形详解
本文章主要是介绍绘制图形/对象的操作,前面是对画布的操作,这里介绍了对象的操作
前言
上一篇文章介绍了画布的一些操作,文本将介绍对象/图形的一些操作。在第2篇文章里面有介绍部分属性,这里会介绍其它的一些针对图形对象的操作
提示:以下是本篇文章正文内容,下面案例可供参考
一、对象的基本属性
这一块在进行图形绘制的时候介绍了部分,这里再回顾一下;
rect.top = 100 // y坐标
rect.left = 100 // x坐标
rect.width = 100 // 矩形宽度
rect.height = 100 // 矩形高度
circle.radius = 50 // 圆半径
rect.fill = '#17b978' // 填充色
rect.stroke = '#FE5332' // 线条颜色
rect.strokeWidth = 10 // 线条宽度
rect.strokeMiterLimit = index // 可以用来记录当前选中的rectList列表的索引!!!!!
circle.selectable = false // 控件不能被选择,不会被操作
circle.hasControls = false // 只能移动不能(编辑)操作
circle.hasBorders = false // 选中时,是否显示边,true:显示(默认)
circle.borderColor = 'red' // 选中时,边的颜色
circle.borderScaleFactor = 5 // 选中时,边的粗细
circle.borderDashArray = [20, 5, 10, 7] // 选中时,虚线边的规则
circle.transparentCorners = false // 选中时,角是否是空心 true:空心 false:实心
circle.cornerColor = "#a1de93", // 选中时,角的颜色
circle.cornerStrokeColor = 'pink' // 选中时,角的边框的颜色
circle.cornerStyle = 'circle' // 选中时,角的属性 rect:矩形(默认)、circle:圆形
circle.cornerSize = 20 // 选中时,角的大小为20
circle.cornerDashArray = [10, 2, 6] // 选中时,虚线角的规则
circle.selectionBackgroundColor = '#ffc300' // 选中时,选框的背景色
circle.padding = 20 // 选中时,选框离图形的距离
circle.borderOpacityWhenMoving = 0.6 // 当对象活动和移动时,对象控制边界的不透明度
triangle.perPixelTargetFind = true // 选择三角形空白位置的时候无法选中,false:可以选中(默认)
let text = new fabric.Text('Hello World!', {
left: 40,
top: 10,
fontFamily: 'Comic Sans', // 字体
fontSize: 60, // 字号
fontWeight: 600, // 字体重量(粗细),normal、bold 或 数字(100、200、400、600、800)
fontStyle: 'normal', // 字体风格 正常 normal 或 斜体 italic
charSpacing: 100, // 字距
fill: 'red', // 字体颜色
cornerColor: 'pink', // 角的颜色(被选中时)
angle: 30, // 旋转
backgroundColor: '#ffd460', // 背景色
borderColor: 'yellowGreen', // 边框颜色(被选中时)
borderScaleFactor: 4, // 边框粗细(被选中时)
borderDashArray: [10, 4, 20], // 创建边框虚线
stroke: '#3f72af', // 文字描边颜色(蓝色)
strokeWidth: 2, // 文字描边粗细
textAlign: 'left', // 对齐方式:left 左对齐; right 右对齐; center 居中
opacity: 0.8, // 不透明度
// text: '雷猴', // 文字内容,会覆盖之前设置的值
selectable: true, // 能否被选中,默认true
shadow: 'rgba(0, 0, 0, 0.5) 5px 5px 5px', // 投影
})
canvas.add(text)
二、高级操作
1.图层操作
this.canvas.bringToFront(rect) // 移到顶层
this.canvas.sendToBack(rect) // 移到底层
this.canvas.bringForward(rect) // 上移一层
this.canvas.sendBackwards(rect) // 下移一层
this.canvas.moveTo(0) // 移动到指定层
2.图形复制
handleCopy() {
if (!canvas.getActiveObject()) {
this.$message.warning('请先选择元素')
return
}
this.canvas.getActiveObject().clone(cloned => {
this.cloneObjects = cloned
})
}
3.图形粘贴
handlePaste() {
if (!this.cloneObjects) {
return this.$message.warning('还没复制过任何内容')
}
this.cloneObjects.clone(cloned => {
this.canvas.discardActiveObject() // 取消选择
// 设置新内容的坐标位置
cloned.set({
left: cloned.left + 10,
top: cloned.top + 10,
evented: true
})
if (cloned.type === 'activeSelection') { // 如果复制的是多个对象,则需要遍历克隆对象
cloned.canvas = this.canvas;
cloned.forEachObject(obj => {
this.canvas.add(obj)
})
cloned.setCoords()
} else {
this.canvas.add(cloned)
}
this.cloneObjects.top += 10
this.cloneObjects.left += 10
this.canvas.setActiveObject(cloned)
this.canvas.requestRenderAll()
})
}
4.图形锁定
4.1静止水平移动(lockMovementX)
let rect = new fabric.Rect({
width: 100,
height: 50,
fill: '#ffde7d',
top: 20,
left: 20
})
rect.lockMovementX = true
canvas.add(rect)
4.2静止垂直移动(lockMovementY)
let rect = new fabric.Rect({
width: 100,
height: 50,
fill: '#ffde7d',
top: 20,
left: 20
})
rect.lockMovementY = true
4.3静止旋转(lockRotation)
let rect = new fabric.Rect({
width: 100,
height: 50,
fill: '#ff9a3c',
top: 60,
left: 160
})
rect.lockRotation = true
4.4静止水平缩放(lockScalingX)
let rect = new fabric.Rect({
width: 100,
height: 50,
fill: '#ffde7d',
top: 20,
left: 20
})
rect.lockScalingX = true
4.5静止垂直缩放(lockScalingY)
let rect = new fabric.Rect({
width: 100,
height: 50,
fill: '#f95959',
top: 20,
left: 20
})
rect.lockScalingY = true
4.6限制拖动区域
let boundingBox = new fabric.Rect({
top: 100,
left: 100,
width: 600,
height: 400,
fill: '#f95959',
selectable: false
})
let movingBox = new fabric.Rect({
top: 150,
left: 150,
width: 100,
height: 100,
fill: 'yellow',
hasBorders: false,
hasControls: false,
hoverCursor: 'move'
})
this.canvas.add(boundingBox);
this.canvas.add(movingBox);
this.canvas.on("object:moving", (opt) => {
let top = movingBox.top;
let left = movingBox.left;
let topBound = boundingBox.top;
let bottomBound = topBound + boundingBox.height;
let leftBound = boundingBox.left;
let rightBound = leftBound + boundingBox.width;
opt.target.left = Math.min(Math.max(left, leftBound), rightBound - movingBox.width)
opt.target.top = Math.min(Math.max(top, topBound), bottomBound - movingBox.height)
})
5.图形分组
Groups是Fabric最强大的功能之一,它可以将任意数量的Fabric对象组合在一起,形成一个小组,分组后,所有对象都可以一起移动、修改、缩放、旋转甚至更改其外观等
let group = new fabric.Group([circle, text], {
left: 100,
top: 100,
angle: -10
})
canvas.add(group)
把圆和文本组合在了一起
修改分组的某个对象的属性:
group.item(0).set("fill","red");
group.item(1).set({
text:"trololo",
fill:"white"
})
Fabric.js 的组提供了很多方法,这里列一些常用的:
- getObjects() 返回一组中所有对象的数组
- size() 所有对象的数量
- contains() 检查特定对象是否在 group 中
- item() 组中元素
- forEachObject() 遍历组中对象
- add() 添加元素对象
- remove() 删除元素对象
- fabric.util.object.clone() 克隆
打散分组:
// 取消组
function ungroup() {
// 判断当前有没有选中元素,如果没有就不执行任何操作
if (!canvas.getActiveObject()) {
return
}
// 判断当前是否选中组,如果不是,就不执行任何操作
if (canvas.getActiveObject().type !== 'group') {
return
}
// 先获取当前选中的对象,然后打散
canvas.getActiveObject().toActiveSelection()
}
6.图形动画
每个Fabric对象都有一个animate方法,该方法可以动画化该对象,animate(动画属性,动画的结束值,[动画的详细信息(用于指定动画的详细信息-持续时间,回调,缓动等)]),如:
let rect = new fabric.Rect({
left: 100,
top: 100,
width: 100,
height: 100,
fill: 'red'
})
rect.animate("angle", 45, {
onChange: canvas.renderAll.bind(canvas)
})
canvas.add(rect)
rect.animate("angle", 45, {
from: 0, // 允许指定可设置动画的属性的起始值(如果我们不希望使用当前值)
duration: 1000, // 默认为500(ms),可用于更改动画的持续时间
easing: fabric.util.ease.easeOutBounce, // 缓动功能 easeOutBounce、easeInCubic、easeOutCubic、easeInElastic、easeOutElastic、easeInBounce、easeOutExpo
onChange: canvas.renderAll.bind(canvas), // 在每次刷新时都会执行
onComplete: (e) => { console.log(e) } // 在动画结束时调用的回调
})
animate的一个方便之处在于它还支持相对值:
// 向右移动100px
rect.animate('left', '+=100', {
onChange: canvas.renderAll.bind(canvas)
})
// 逆时针旋转5度
rect.animate('angle', '-=5', {
onChange: canvas.renderAll.bind(canvas)
})
7.图形滤镜
fabric.Image的每个实例都具有“ filters”属性,该属性是一个简单的过滤器数组。该阵列中的每个过滤器都是Fabric过滤器之一的实例。
<template>
<div>
<canvas width="500" height="500" id="canvas" style="border: 1px solid #ccc;"></canvas>
</div>
</template>
<script setup>
import { onMounted } from 'vue'
import { fabric } from 'fabric'
import gwen from '@/assets/images/gwen-spider-verse-ah.jpg'
function init() {
const canvas = new fabric.Canvas('canvas')
fabric.Image.fromURL(gwen, img => {
img.scale(0.5) // 图片缩小50%
canvas.add(img)
})
// 单个滤镜
fabric.Image.fromURL(gwen, img => {
img.scale(0.5) // 图片缩小50%
img.left = 250
// 添加滤镜
img.filters.push(new fabric.Image.filters.Grayscale())
// 图片加载完成之后,应用滤镜效果
img.applyFilters()
canvas.add(img)
})
// 叠加滤镜
// “filters”属性是一个数组,我们可以用数组方法执行任何所需的操作:移除滤镜(pop,splice,shift),添加滤镜(push,unshift,splice),甚至可以组合多个滤镜。当我们调用 applyFilters 时,“filters”数组中存在的任何滤镜将逐个应用,所以让我们尝试创建一个既色偏又明亮(Brightness)的图像。
fabric.Image.fromURL(gwen, img => {
img.scale(0.5) // 图片缩小50%
// 添加滤镜
img.filters.push(
new fabric.Image.filters.Grayscale(),
new fabric.Image.filters.Sepia(), //色偏
new fabric.Image.filters.Brightness({ brightness: 0.2 }) //亮度
)
// 图片加载完成之后,应用滤镜效果
img.applyFilters()
img.set({
left: 250,
top: 250,
})
canvas.add(img)
})
}
onMounted(() => {
init()
})
</script>
fabric 内置滤镜:
- BaseFilter 基本过滤器
- Blur 模糊
- Brightness 亮度
- ColorMatrix 颜色矩阵
- Contrast 对比
- Convolute 卷积
- Gamma 伽玛
- Grayscale 灰度
- HueRotation 色调旋转
- Invert 倒置
- Noise 噪音
- Pixelate 像素化
- RemoveColor 移除颜色
- Resize 调整大小
- Saturation 饱和
- Sepia 色偏
8.对象的选中
8.1禁止选中
// 元素禁止选中
rect.selectable = false
8.2空白位置无法选中元素
canvas.selectionFullyContained = true // 只选择完全包含在拖动选择矩形中的形状
8.3画布框选样式
canvas.selectionColor = 'rgba(106, 101, 216, 0.3)' // 画布鼠标框选时的背景色
canvas.selectionBorderColor = "#1d2786" // 画布鼠标框选时的边框颜色
canvas.selectionLineWidth = 6 // 画布鼠标框选时的边框厚度
canvas.selectionDashArray = [30, 4, 10] // 画布鼠标框选时边框虚线规则
8.4自定义边和控制角样式
// 圆形
const circle = new fabric.Circle({
radius: 30,
fill: '#f55',
top: 70,
left: 70
})
circle.set({
borderColor: 'red', // 边框颜色
cornerColor: 'green', // 控制角颜色
cornerSize: 10, // 控制角大小
transparentCorners: false // 控制角填充色不透明
selectionBackgroundColor: 'orange' // 选中后,背景色变橙色
})
canvas.add(circle)
canvas.setActiveObject(circle) // 选中圆
// 圆形
const circle = new fabric.Circle({
radius: 30,
fill: '#f55',
top: 70,
left: 70
})
circle.hasBorders = false // 取消边框
circle.hasControls = false // 禁止控制角
canvas.hoverCursor = 'wait' // 设置等待指针的样式
canvas.selection = false // 不允许直接从画布框选
canvas.add(circle)
canvas.setActiveObject(circle) // 选中第一项
总结
本文章主要是介绍绘制图形/对象的操作,前面是对画布的操作,这里介绍了对象的操作,后续就可以开始进行自由绘制的基础功能的撰写了
更多推荐
所有评论(0)