本文介绍: Fabric.js 是一个功能强大且操作简单的 Javascript HTML5 canvas 工具库。缩放 scaleX 和 scaleY。反转 scaleX 和 scaleY。平移 top 和 left。以鼠标指针为基准缩放画布。fabric 内置滤镜。旋转角度 angle。以原点为基准缩放画布。自定义边和控制角样式。……
Fabric.js 是一个功能强大且操作简单的 Javascript HTML5 canvas 工具库。
文档:
npm i fabric --save
基本示例
<canvas id="canvas"
width="400"
height="400"
style="border: 1px solid #ccc;"
></canvas>
import { fabric } from 'fabric'
// 使用 fabric 接管容器 传入canvas的id
const canvas = new fabric.Canvas('canvas')
// 创建一个长方形
const rect = new fabric.Rect({
top: 30, // 距离容器顶部 30px
left: 30, // 距离容器左侧 30px
width: 100, // 宽 100px
height: 60, // 高 60px
fill: 'red' // 填充 红色
})
// 将矩形(rect)加入到canvas画布中
canvas.add(rect)
画布
// 可交互的画布
const canvas = new fabric.Canvas('canvas')
// 不可交互的画布
const canvas = new fabric.StaticCanvas('canvas')
// 设定画布参数
const canvas = new fabric.Canvas('canvas', {
width: 300, // 画布宽度
height: 300, // 画布高度
backgroundColor: '#eee', // 画布背景色
// 元素对象被选中时保持原有层级
preserveObjectStacking: true, // 默认false
// 输出一个精简后的 JSON
includeDefaultValues: false
})
使用背景图
setBackgroundImage(image, callback, optionsopt) → {fabric.Canvas}
参数 | 类型 | 属性 | 描述 |
---|---|---|---|
image | fabric.Image、String | – | fabric.Image instance or URL of an image to set background to |
callback | function | – | Callback to invoke when image is loaded and set as background |
options | Object | <optional> |
Optional options to set for the background image. |
let imageUrl = 'http://fabricjs.com/assets/honey_im_subtle.png'
// 设置背景图
// 方法一:设置图片地址
canvas.setBackgroundImage(
imageUrl,
canvas.renderAll.bind(canvas)
)
// 方法二:使用 fabric.Image.fromURL
fabric.Image.fromURL(imageUrl,
(img) => {
canvas.setBackgroundImage(
img,
canvas.renderAll.bind(canvas)
)
}
)
// 旋转背景图
canvas.setBackgroundImage(
imageUrl,
canvas.renderAll.bind(canvas),
{
angle: 15
}
)
// 拉伸背景图, 使图片充满全屏
canvas.setBackgroundImage(
imageUrl,
canvas.renderAll.bind(canvas),
{
scaleX: canvas.width / img.width, // 计算出图片要拉伸的宽度
scaleY: canvas.height / img.height // 计算出图片要拉伸的高度
}
)
// 重复背景图
canvas.setBackgroundColor(
{
source: imageUrl,
repeat: 'repeat'
},
canvas.renderAll.bind(canvas)
)
// 设置覆盖图像的画布
// setOverlayImage(image, callback, optionsopt)
canvas.setOverlayImage(
imageUrl,
canvas.renderAll.bind(canvas)
)
// 水平垂直居中
canvas.backgroundImage.center()
基础图形
const rect = new fabric.Rect({
top: 100, // 距离容器顶部 100px
left: 100, // 距离容器左侧 100px
fill: 'orange', // 填充 橙色
width: 100, // 宽度 100px
height: 100 // 高度 100px
})
const rect = new fabric.Rect({
top: 100, // 距离容器顶部 100px
left: 100, // 距离容器左侧 100px
fill: 'orange', // 填充 橙色
width: 100, // 宽度 100px
height: 100, // 高度 100px
rx: 20, // x轴的半径
ry: 20 // y轴的半径
})
圆形
const circle = new fabric.Circle({
top: 100,
left: 100,
radius: 50, // 圆的半径 50
fill: 'green'
})
椭圆形
const ellipse = new fabric.Ellipse({
top: 20,
left: 20,
rx: 70,
ry: 30,
fill: 'hotpink'
})
const triangle = new fabric.Triangle({
top: 100,
left: 100,
width: 80, // 底边长度
height: 100, // 底边到对角的距离
fill: 'blue'
})
const line = new fabric.Line(
[
10, 10, // 起始点坐标
200, 300 // 结束点坐标
],
{
stroke: 'red', // 笔触颜色
}
)
折线
// 不会自动把 起始点 和 结束点 自动闭合
const polyline = new fabric.Polyline([
{x: 30, y: 30},
{x: 150, y: 140},
{x: 240, y: 150},
{x: 100, y: 30}
], {
fill: 'transparent', // 如果画折线,需要填充透明
stroke: '#6639a6', // 线段颜色:紫色
strokeWidth: 5 // 线段粗细 5
})
// 会自动把 起始点 和 结束点 连接起来
const polygon = new fabric.Polygon([
{x: 30, y: 30},
{x: 150, y: 140},
{x: 240, y: 150},
{x: 100, y: 30}
], {
fill: '#ffd3b6', // 填充色
stroke: '#6639a6', // 线段颜色:紫色
strokeWidth: 5 // 线段粗细 5
})
绘制路径
// 绘制路径
const path = new fabric.Path('M 0 0 L 200 100 L 170 200 z')
path.set({
top: 50, // 距离容器顶部距离 50px
left: 50, // 距离容器左侧距离 50px
fill: 'hotpink', // 填充 亮粉色
opacity: 0.5, // 不透明度 50%
stroke: 'black', // 描边颜色 黑色
strokeWidth: 10 // 描边粗细 10px
})
M:可以理解为新的起始点x,y坐标
L:每个折点的x,y坐标
z:自动闭合(自动把结束点和起始点连接起来)
文本
普通文本
const text = new fabric.Text('雷猴啊')
const itext = new fabric.IText('雷猴啊')
// 内容可编辑
const textbox = new fabric.Textbox('Lorum ipsum dolor sit amet', {
width: 250
})
基础样式
const circle = new fabric.Circle({
top: 100,
left: 100,
radius: 50, // 半径:50px
backgroundColor: 'green', // 背景色:绿色
fill: 'orange', // 填充色:橙色
stroke: '#f6416c', // 边框颜色:粉色
strokeWidth: 5, // 边框粗细:5px
strokeDashArray: [20, 5, 14], // 边框虚线规则:填充20px 空5px 填充14px 空20px 填充5px ……
shadow: '10px 20px 6px rgba(10, 20, 30, 0.4)', // 投影:向右偏移10px,向下偏移20px,羽化6px,投影颜色及透明度
transparentCorners: false, // 选中时,角是被填充了。true 空心;false 实心
borderColor: '#16f1fc', // 选中时,边框颜色:天蓝
borderScaleFactor: 5, // 选中时,边的粗细:5px
borderDashArray: [20, 5, 10, 7], // 选中时,虚线边的规则
cornerColor: "#a1de93", // 选中时,角的颜色是 青色
cornerStrokeColor: 'pink', // 选中时,角的边框的颜色是 粉色
cornerStyle: 'circle', // 选中时,叫的属性。默认rect 矩形;circle 圆形
cornerSize: 20, // 选中时,角的大小为20
cornerDashArray: [10, 2, 6], // 选中时,虚线角的规则
selectionBackgroundColor: '#7f1300', // 选中时,选框的背景色:朱红
padding: 40, // 选中时,选择框离元素的内边距:40px
borderOpacityWhenMoving: 0.6, // 当对象活动和移动时,对象控制边界的不透明度
})
const text = new fabric.Text('雷猴', {
top: 40,
left: 40,
fontSize: 120,
backgroundColor: 'green', // 背景色:绿色
fill: 'orange', // 填充色:橙色
stroke: '#f6416c', // 边框颜色:粉色
strokeWidth: 3, // 边框粗细:3px
strokeDashArray: [20, 5, 14], // 边框虚线规则:填充20px 空5px 填充14px 空20px 填充5px ……
shadow: '10px 20px 6px rgba(10, 20, 30, 0.4)', // 投影:向右偏移10px,向下偏移20px,羽化6px,投影颜色及透明度
transparentCorners: false, // 选中时,角是被填充了。true 空心;false 实心
borderColor: '#16f1fc', // 选中时,边框颜色:天蓝
borderScaleFactor: 5, // 选中时,边的粗细:5px
borderDashArray: [20, 5, 10, 7], // 选中时,虚线边的规则
cornerColor: "#a1de93", // 选中时,角的颜色是 青色
cornerStrokeColor: 'pink', // 选中时,角的边框的颜色是 粉色
cornerStyle: 'circle', // 选中时,叫的属性。默认rect 矩形;circle 圆形
cornerSize: 20, // 选中时,角的大小为20
cornerDashArray: [10, 2, 6], // 选中时,虚线角的规则
selectionBackgroundColor: '#7f1300', // 选中时,选框的背景色:朱红
padding: 40, // 选中时,选择框离元素的内边距:40px
borderOpacityWhenMoving: 0.6, // 当对象活动和移动时,对象控制边界的不透明度
})
const overline = new fabric.Text('文本', {
top: 30,
left: 10,
fontSize: 20,
overline: true, // 上划线
underline: true, // 下划线
linethrough: true, // 删除线
textAlign: 'left', // 左对齐
// textAlign: 'center',// 居中对齐
// textAlign: 'right', // 右对齐
lineHeight: 1, // 行高
fontStyle: 'italic', // 斜体
})
渐变
// 圆
let circle = new fabric.Circle({
left: 100,
top: 100,
radius: 50,
})
// 线性渐变
let gradient = new fabric.Gradient({
type: 'linear', // linear or radial
gradientUnits: 'pixels', // pixels or pencentage 像素 或者 百分比
coords: { x1: 0, y1: 0, x2: circle.width, y2: 0 }, // 至少2个坐标对(x1,y1和x2,y2)将定义渐变在对象上的扩展方式
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', gradient);
径向渐变
let gradient = new fabric.Gradient({
type: 'radial',
coords: {
r1: 50, // 该属性仅径向渐变可用,外圆半径
r2: 0, // 该属性仅径向渐变可用,外圆半径
x1: 50, // 焦点的x坐标
y1: 50, // 焦点的y坐标
x2: 50, // 中心点的x坐标
y2: 50, // 中心点的y坐标
},
colorStops: [
{ offset: 0, color: '#fee140' },
{ offset: 1, color: '#fa709a' }
]
})
使用图片
使用HTML的图片
const imgElement = document.getElementById('logo')
let imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
width: 200,
height: 200,
angle: 50, // 旋转
})
canvas.add(imgInstance)
fabric.Image.fromURL(imageUrl, image => {
image.scale(0.5) // 缩放
canvas.add(image) // 将图片加入到画布
})
图片滤镜
单个滤镜
fabric.Image.fromURL(imageUrl, img => {
img.scale(0.5) // 图片缩小50%
img.left = 250
// 添加滤镜
img.filters.push(new fabric.Image.filters.Grayscale())
// 图片加载完成之后,应用滤镜效果
img.applyFilters()
canvas.add(img)
})
叠加滤镜
fabric.Image.fromURL(imageUrl, 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)
})
fabric 内置滤镜
BaseFilter 基本过滤器
Blur 模糊
Brightness 亮度
ColorMatrix 颜色矩阵
Contrast 对比
Convolute 卷积
Gamma 伽玛
Grayscale 灰度
HueRotation 色调旋转
Invert 倒置
Noise 噪音
Pixelate 像素化
RemoveColor 移除颜色
Resize 调整大小
Saturation 饱和
Sepia 色偏
转换
旋转角度 angle
let triangle = new fabric.Triangle({
top: 100,
left: 100,
width: 80,
height: 100,
fill: 'blue',
angle: 30 // 旋转30度
})
let triangle = new fabric.Triangle({
top: 100,
left: 100,
width: 80,
height: 100,
fill: 'blue',
scaleX: 2, // x轴方向放大2倍
scaleY: 2 // y轴方向放大2倍
})
反转 scaleX 和 scaleY
let triangle = new fabric.Triangle({
top: 100,
left: 100,
width: 80,
height: 100,
fill: 'blue',
scaleY: -1 // scale是负数时,图形会反转
})
平移 top 和 left
let triangle = new fabric.Triangle({
top: 100, // 移动
left: 100,
width: 80,
height: 100,
fill: 'blue',
})
分组
建组
const canvas = new fabric.Canvas('canvas')
// 椭圆
const ellipse = new fabric.Ellipse({
top: 20,
left: 20,
rx: 100,
ry: 50,
fill: '#ddd',
originX: 'center', // 旋转x轴:left, right, center
originY: 'center' // 旋转y轴:top, bottom, center
})
// 文本
const text = new fabric.Text('Hello World', {
top: 40,
left: 20,
fontSize: 20,
originX: "center",
originY: "center"
})
// 建组
const group = new fabric.Group([ellipse, text], {
top: 50, // 整组距离顶部100
left: 100, // 整组距离左侧100
angle: -10, // 整组旋转-10deg
})
canvas.add(group)
操作组
常用组方法
getObjects() // 返回一组中所有对象的数组
size() // 所有对象的数量
contains() // 检查特定对象是否在 group 中
item() // 组中元素
forEachObject() // 遍历组中对象
add() // 添加元素对象
remove() // 删除元素对象
fabric.util.object.clone() // 克隆
// 控制第一个元素(椭圆)
group.item(0).set('fill', '#ea5455')
// 控制第二个元素(文本)
group.item(1).set({
text: '雷猴,世界',
fill: '#fff'
})
打散分组
group.toActiveSelection()
// 先获取当前选中的对象,然后打散
canvas.getActiveObject().toActiveSelection()
动画
绝对值动画
const rect = new fabric.Rect({
left: 100,
top: 100,
width: 100,
height: 100,
fill: 'red'
})
// 设置矩形动画
// animate(动画属性, 动画的结束值, [画的详细信息])
rect.animate('angle', "-50", {
// // 每次刷新的时候都会执行
onChange: canvas.renderAll.bind(canvas),
})
// {
// rom:允许指定可设置动画的属性的起始值(如果我们不希望使用当前值)。
// duration:默认为500(ms)。可用于更改动画的持续时间。
// onComplete:在动画结束时调用的回调。
// easing:缓动功能。
// }
相对值动画
// 请注意第二个参数:+=360
rect.animate('angle', '+=360', {
onChange:canvas.renderAll.bind(canvas), // 每次刷新的时候都会执行
duration: 2000, // 执行时间
easing: fabric.util.ease.easeOutBounce, // 缓冲效果
})
事件
官方案例: http://fabricjs.com/events
const rect = new fabric.Rect({
top: 20,
left: 20,
width: 100,
height: 50,
fill: '#9896f1'
})
// 给矩形添加一个选中事件
rect.on('selected', options => {
console.log('选中矩形啦', options)
})
// 添加画布点击事件
canvas.on('mouse:down', options => {
console.log(`x轴坐标: ${options.e.clientX}; y轴坐标: ${options.e.clientY}`)
})
// 移除画布点击事件
canvas.off('mouse:down')
自由绘画
const canvas = new fabric.Canvas('canvas', {
isDrawingMode: true, // 开启绘图模式
})
// 设置画笔颜色
canvas.freeDrawingBrush.color = '#11999e'
// 设置画笔粗细
canvas.freeDrawingBrush.width = 10
// 画笔投影
canvas.freeDrawingBrush.shadow = new fabric.Shadow({
blur: 10,
offsetX: 10,
offsetY: 10,
affectStroke: true,
color: '#30e3ca',
})
禁止部分操作
const rect = new fabric.Rect({
top: 100,
left: 100,
width: 100,
height: 50,
fill: '#ffde7d'
})
// 不允许水平移动
rect.lockMovementX = true
// 不允许垂直移动
rect.lockMovementY = true
// 禁止旋转
rect.lockRotation = true
// 禁止水平缩放
rect.lockScalingX = true
// 禁止垂直缩放
rect.lockScalingY = true
// 不允许直接从画布框选
canvas.selection = false
缩放和平移画布
缩放画布
// 监听鼠标滚轮事件
canvas.on('mouse:wheel', opt => {
let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
// 控制缩放范围在 0.01~20 的区间内
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
// 设置画布缩放比例
canvas.setZoom(zoom)
})
// 监听鼠标滚轮事件
canvas.on('mouse:wheel', opt => {
let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
// 控制缩放范围在 0.01~20 的区间内
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
// 设置画布缩放比例
// 关键点!!!
// 参数1:将画布的所放点设置成鼠标当前位置
// 参数2:传入缩放值
canvas.zoomToPoint(
{
x: opt.e.offsetX, // 鼠标x轴坐标
y: opt.e.offsetY // 鼠标y轴坐标
},
zoom // 最后要缩放的值
)
})
平移画布
canvas.on('mouse:down', opt => { // 鼠标按下时触发
let evt = opt.e
if (evt.altKey === true) { // 是否按住alt
canvas.isDragging = true // isDragging 是自定义的,开启移动状态
canvas.lastPosX = evt.clientX // lastPosX 是自定义的
canvas.lastPosY = evt.clientY // lastPosY 是自定义的
}
})
canvas.on('mouse:move', opt => { // 鼠标移动时触发
if (canvas.isDragging) {
let evt = opt.e
let vpt = canvas.viewportTransform // 聚焦视图的转换
vpt[4] += evt.clientX - canvas.lastPosX
vpt[5] += evt.clientY - canvas.lastPosY
canvas.requestRenderAll() // 重新渲染
canvas.lastPosX = evt.clientX
canvas.lastPosY = evt.clientY
}
})
canvas.on('mouse:up', opt => { // 鼠标松开时触发
canvas.setViewportTransform(canvas.viewportTransform) // 设置此画布实例的视口转换
canvas.isDragging = false // 关闭移动状态
})
选中状态
const rect = new fabric.Rect({
top: 100,
left: 100,
width: 200,
height: 100,
fill: 'red'
})
// 元素禁止选中
rect.selectable = false
// 选择三角形空白位置的时候无法选中
rect.perPixelTargetFind = true
// 只选择完全包含在拖动选择矩形中的形状
canvas.selectionFullyContained = true
画布框选样式
canvas.selection = true // 画布是否可选中。默认true;false 不可选中
canvas.selectionColor = 'rgba(106, 101, 216, 0.3)' // 画布鼠标框选时的背景色
canvas.selectionBorderColor = "#1d2786" // 画布鼠标框选时的边框颜色
canvas.selectionLineWidth = 6 // 画布鼠标框选时的边框厚度
canvas.selectionDashArray = [30, 4, 10] // 画布鼠标框选时边框虚线规则
canvas.selectionFullyContained = true // 只选择完全包含在拖动选择矩形中的形状
// 圆形
const circle = new fabric.Circle({
radius: 30,
fill: '#f55',
top: 70,
left: 70
})
circle.set({
borderColor: 'red', // 边框颜色
cornerColor: 'green', // 控制角颜色
cornerSize: 10, // 控制角大小
transparentCorners: false, // 控制角填充色不透明
// transparentCorners: true // 控制角填充色透明
selectionBackgroundColor: 'orange' // 选中后,背景色变橙色
})
circle.hasBorders = false // 取消边框
circle.hasControls = false // 禁止控制角
canvas.hoverCursor = 'wait' // 设置等待指针
canvas.add(circle)
canvas.setActiveObject(circle) // 选中圆
元素移动时的样式
function animate(e, dir) {
if (e.target) {
fabric.util.animate({
startValue: e.target.get('angle'),
endValue: e.target.get('angle') + (dir ? 10 : -10),
duration: 100
})
fabric.util.animate({
startValue: e.target.get('scaleX'),
endValue: e.target.get('scaleX') + (dir ? 0.2 : -0.2),
duration: 100,
onChange: function(value) {
e.target.scale(value)
canvas.renderAll()
},
onComplete: function() {
e.target.setCoords()
}
})
}
}
canvas.on('mouse:down', function(e) { animate(e, 1) })
canvas.on('mouse:up', function(e) { animate(e, 0) })
序列化
// 输出json
JSON.stringify(canvas)
canvas.toJSON()
canvas.toObject()
// 输出png(base64版)可能会打断 canvas 的渲染
canvas.toDataURL('png')
canvas.requestRenderAll()
// 输出 SVG
canvas.toSVG()
反序列化
const str = '{"version":"4.6.0","objects":[{"type":"rect","version":"4.6.0","originX":"left","originY":"top","left":50,"top":50,"width":20,"height":20,"fill":"green","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"rx":0,"ry":0},{"type":"circle","version":"4.6.0","originX":"left","originY":"top","left":80,"top":80,"width":80,"height":80,"fill":"red","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeUniform":false,"strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","skewX":0,"skewY":0,"radius":40,"startAngle":0,"endAngle":6.283185307179586}],"background":"#ddd"}'
// 初始化画布
const canvas = new fabric.Canvas('canvas')
// 反序列化
canvas.loadFromJSON(str)
fabric类的继承体系
StaticCanvas
Canvas
Object
Triangle
Circle
Ellipse
Image
Line
Path
Rect
Polyline
Polygon
Group
ActiveSelection
Text
IText
Textbox
BaseBrush
PatternBrush
PencilBrush
SprayBrush
Point
CircleBrush
Gradient
Color
Intersection
Pattern
Shadow
BaseFilter
Blur
Brightness
ColorMatrix
Contrast
Convolute
BlendColor
BlendImage
Gamma
Grayscale
HueRotation
Invert
Noise
Pixelate
RemoveColor
Resize
Saturation
Vibrance
原文地址:https://blog.csdn.net/mouday/article/details/125941299
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_22162.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。