html5-canvas – Fabric.js画布上的多个裁剪区域

前端之家收集整理的这篇文章主要介绍了html5-canvas – Fabric.js画布上的多个裁剪区域前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
对于制作 Photo Collage Maker,我使用具有基于对象的裁剪功能的面料js.该功能非常好,但是裁剪区域内的图像无法缩放,移动或旋转.我想要固定位置裁剪区域,图像可以根据用户想要定位在固定裁剪区域内.

我google了,找到非常接近的解决方

  1. var canvas = new fabric.Canvas('c');
  2. var ctx = canvas.getContext("2d");
  3. ctx.beginPath();
  4. ctx.rect(10,10,150,150);
  5. ctx.rect(180,200,200);
  6. ctx.closePath();
  7. ctx.stroke();
  8. ctx.clip();

Multiple Clipping Areas on fabric js canvas

其中一个裁剪区域的图像出现在另一裁剪区域中.如何避免这种情况,或者有另一种使用fabric js来完成这种方式的方法.

解决方法

这可以通过使用clipTo属性的Fabric来实现,但是必须在clipTo函数中反转转换(缩放和旋转).

当您在Fabric中使用clipTo属性时,缩放和旋转将在剪辑后应用,这意味着剪切与图像进行缩放和旋转.您必须通过在clipTo属性函数中应用转换的准确相反来对抗.

我的解决方案涉及到一个Fabric.Rect作为剪辑区域的“占位符”(这具有优点,因为您可以使用Fabric来移动对象,从而将剪辑区域移动.

请注意,我的解决方案使用Lo-Dash实用程序库,特别是_.bind()(参见上下文的代码).

Example Fiddle

分解

1.初始化面料

首先我们想要我们的画布,当然是:

  1. var canvas = new fabric.Canvas('c');

2.剪辑区域

  1. var clipRect1 = new fabric.Rect({
  2. originX: 'left',originY: 'top',left: 180,top: 10,width: 200,height: 200,fill: 'none',stroke: 'black',strokeWidth: 2,selectable: false
  3. });

我们给这些Rect对象一个名称属性clipFor,所以clipTo函数可以找到他们想要剪切的对象:

  1. clipRect1.set({
  2. clipFor: 'pug'
  3. });
  4. canvas.add(clipRect1);

不必是剪辑区域的实际对象,但它可以更轻松地进行管理,因为您可以使用Fabric移动它.

剪切功能

我们定义要由图像的clipTo属性单独使用的功能,以避免代码重复:

由于Image对象的angle属性以度为单位存储,我们将使用此属性将其转换为弧度.

  1. function degToRad(degrees) {
  2. return degrees * (Math.PI / 180);
  3. }

findByClipName()是一个方便的函数,它正在使用Lo-Dash,找到要剪切的Image对象的clipFor属性(例如,在下面的图片中,name将为“pug”):

  1. function findByClipName(name) {
  2. return _(canvas.getObjects()).where({
  3. clipFor: name
  4. }).first()
  5. }

这是工作的一部分:

  1. var clipByName = function (ctx) {
  2. var clipRect = findByClipName(this.clipName);
  3. var scaleXTo1 = (1 / this.scaleX);
  4. var scaleYTo1 = (1 / this.scaleY);
  5. ctx.save();
  6. ctx.translate(0,0);
  7. ctx.rotate(degToRad(this.angle * -1));
  8. ctx.scale(scaleXTo1,scaleYTo1);
  9. ctx.beginPath();
  10. ctx.rect(
  11. clipRect.left - this.left,clipRect.top - this.top,clipRect.width,clipRect.height
  12. );
  13. ctx.closePath();
  14. ctx.restore();
  15. }

注意:在上面的功能中,请参见下面的使用说明.

4. fabric.Image对象使用clipByName()

最后,可以实例化图像,并使用clipByName函数,如下所示:

  1. var pugImg = new Image();
  2. pugImg.onload = function (img) {
  3. var pug = new fabric.Image(pugImg,{
  4. angle: 45,width: 500,height: 500,left: 230,top: 170,scaleX: 0.3,scaleY: 0.3,clipName: 'pug',clipTo: function(ctx) {
  5. return _.bind(clipByName,pug)(ctx)
  6. }
  7. });
  8. canvas.add(pug);
  9. };
  10. pugImg.src = 'http://fabricjs.com/lib/pug.jpg';

_.bind()做什么?

请注意,引用包装在_.bind()函数中.

我使用_.bind()有两个原因:

>我们需要将参考图像对象传递给clipByName()
> clipTo属性传递画布上下文,而不是对象.

基本上,_.bind()允许您创建一个使用您指定的对象作为此上下文的函数的版本.

来源

> http://lodash.com/docs#bind
> http://fabricjs.com/docs/fabric.Object.html#clipTo
> http://html5.litten.com/understanding-save-and-restore-for-the-canvas-context/

猜你在找的HTML5相关文章