fabric.js 问题总结(react)

fabric.js 问题总结(react),第1张

库:GitHub - guanwanxiao/simplest-ts-environment at syq/canvasGitHub - fabricjs/fabric.js: Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) ParserGitHub - guanwanxiao/simplest-ts-environment at syq/canvas

官网:Fabric.js Javascript Canvas Library

中文文档:http://funcion_woqu.gitee.io/fabric-doc/api/#circle

问题list:

npm/yarn安装后引入报错控制器删除、旋转图标修改,边框样式修改缩放最大最小倍数限制添加图片跨域报错调用canvas.toDataURl()报错

解决方案:

npm/yarn安装后引入报错

不管我用npm还是yarn安装,都报各种eslint或者webpack的错误,因为我的项目是服务端渲染,且项目配置都在别的库,不好修改,我用了github上两种导入方式都报错。

const fabric = require("fabric").fabric;
import { fabric } from "fabric";

所以我最终用的bootcdn的线上地址来加载

type="text/javascript"

src="https://cdn.bootcdn.net/ajax/libs/fabric.js/521/fabric.js"

/>

控制器删除、旋转图标修改,边框样式修改

看看fabric原生效果,和我们UI设计的效果对比

 代码实现:

//删除图标实现代码
var delimg = document.createElement('img')
delimg.src = deletepng //deleteIcon
    
function renderDelIcon(ctx, left, top, styleOverride, fabricObject) {
  var size = this.cornerSize
  ctx.save()
  ctx.translate(left, top)
  ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle))
  ctx.drawImage(delimg, -size / 2, -size / 2, size, size)
  ctx.restore()
}

fabric.Object.prototype.controls.deleteControl = new fabric.Control({
  x: -0.5,
  y: -0.5,//这里x y 的正负值代表4个角
  cursorStyle: 'pointer',
  mouseUpHandler: this.deleteObject,//点击事件
  render: renderDelIcon,//渲染函数
  cornerSize: 22,//这里是图片大小
})


//----------------------------------
//旋转图标的实现
var rotaeimg = document.createElement('img')
rotaeimg.src = xuanzhuanpng 

function renderRotaIcon(ctx, left, top, styleOverride, fabricObject) {
  var size = 22 //this.cornerSize
  ctx.save()
  ctx.translate(left, top)
  ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle))
  ctx.drawImage(rotaeimg, -size / 2, -size / 2, size, size)
  ctx.restore()
}

//因为旋转这个功能他本身就有,只是把位置变了,所以不用重新写方法
fabric.Object.prototype.controls.br.actionHandler =
      fabric.Object.prototype.controls.mtr.actionHandler
fabric.Object.prototype.controls.br.render = renderRotaIcon

 原理分析:

fabric.Object.prototype.controls是fabric的控制器对象,在添加之前打个log看下:

正好是8个方向点,加一个旋转点

加一个删除按钮后打个log看下:

 原型链上多了一个deleteControl,就是我们刚才添加的删除按钮。由此可见,通过原型链还可以添加更多的内容到控制器上,同时也可以修改控制器的样式、方法,等

缩放最大最小倍数限制

同样用修改原型链方法实现:

//限制元素放大的倍数
fabric.Object.prototype.on('scaling', function () {
  const maxScaleX = 2
  if (this.scaleX > maxScaleX) {
    this.scaleX = maxScaleX
    this.left = this.lastGoodLeft
    this.top = this.lastGoodTop
  }
  if (this.scaleY > maxScaleX) {
    this.scaleY = maxScaleX
    this.left = this.lastGoodLeft
    this.top = this.lastGoodTop
  }
  this.lastGoodTop = this.top
  this.lastGoodLeft = this.left
})
添加图片跨域报错 调用canvas.toDataURl()报错

这两个问题可以一起讲,获取canvas的base64数据的时候,可能会报错

Access to image at ‘file:‘ from origin ‘null‘ has been blocked by CORS policy

那是因为canvas里面加载了跨图片,导致画布被污染,看看mdn怎么说

 启用了 CORS 的图片 - HTML(超文本标记语言) | MDN

在fabric里面加载图片,且需要导出数据的,需要图片所在域名的域名加 Access-Control-Allow-Origin:*,并且在加载的时候要设置跨域模式,比如:

//fabric加载跨域图片
let imgbg = new Image()//可以不new Image()的,因为我要计算倍数,所以这么写
imgbg.src = url
imgbg.onload = () => {
  let scale = window.innerWidth / 3 / imgbg.width
  fabric.Image.fromURL(url, (img) => {
    img.set({
      left: 50,
      top: 50,
      scaleX: scale,
      scaleY: scale,
    })
    canvas.add(img)
  })
}

我的其他设置可以参考一下:

fabricConfig = () => {
  fabric.Object.prototype.set({
    borderColor: 'white',
    cornerColor: 'white', //激活状态角落图标的填充颜色
    cornerStrokeColor: '', //激活状态角落图标的边框颜色
    borderOpacityWhenMoving: 1,
    borderScaleFactor: 2,
    cornerSize: 8, //操作点的像素
    cornerStyle: 'circle', //rect,circle,操作点是圆点还是小方块
    centeredScaling: false, //角落放大缩小是否是以图形中心为放大原点
    centeredRotation: false, //旋转按钮旋转是否是左上角为圆心旋转
    transparentCorners: false, //激活状态角落的图标是否透明
    rotatingPointOffset: 2, //旋转距旋转体的距离
    originX: 'left',
    originY: 'top',
    // scaleX: 2,//不起作用
    // scaleY: 2,
    lockScalingFlip: true,
    lockUniScaling: true, //当设置为true,Object将无法被锁定比例进行缩放。默认值为false
    hasRotatingPoint: true, //是否显示旋转按钮
    selectionDashArray: [5, 5],
    // minScaleLimit: 0.5,//对整个画布生效
  })
  fabric.Object.prototype.setControlsVisibility({
    ml: false, //中左,中下,中右,中上、旋转五个点隐藏
    mb: false,
    mr: false,
    mt: false,
    mtr: false,
  })

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/1325305.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存