本文介绍: Fabric.js一个功能强大且操作简单的 Javascript HTML5 canvas 工具库。缩放 scaleX 和 scaleY。反转 scaleX 和 scaleY。平移 topleft。以鼠标指针基准缩放画布fabric 内置滤镜。旋转角度 angle。以原点为基准缩放画布自定义边和控制样式。……

Fabric.js一个功能强大且操作简单的 Javascript HTML5 canvas 工具库。

文档

安装

npm i fabric --save

基本示例

创建容器

<canvas id="canvas"
	width="400" 
	height="400" 
	style="border: 1px solid #ccc;"
&gt;</canvas&gt;

绘制图形

import { fabric } from 'fabric'

// 使用 fabric 接管容器 传入canvasid
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)

使用js引入

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度
  })

缩放 scaleX 和 scaleY

 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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注