Fabric toDataUrl with multiplier not working as expected

半城伤御伤魂 提交于 2021-01-29 03:00:46

问题


In my code I created method to clip images using fabric shapes. I have used stackoverflow answer for achieving this. Somehow after using this method I cannot render the canvas using default fabric canvas render method.

var img01URL = 'https://www.google.com/images/srpr/logo4w.png';
var img02URL = 'http://fabricjs.com/lib/pug.jpg';

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

document.getElementById('download').addEventListener('click', function() {
  canvas.renderAll();
  this.href = canvas.toDataURL({
    format: 'png',
    multiplier: 2        
  });
  this.download = "test.png";
}, false);

var clipRect1 = new fabric.Rect({
    originX: 'left',
    originY: 'top',
    angle: 90,
    left: 195,
    top: 0,
    width: 200,
    height: 200,
    fill: '#DDD', /* use transparent for no fill */
    strokeWidth: 1,
    lockMovementX: true,
    lockMovementY: true,
    angle: 5,
    stroke: 'red'
});

var pugImg = new Image();
pugImg.onload = function (img) {    
    var pug = new fabric.Image(pugImg, {
        angle: 0,
        width: 500,
        height: 500,
        left: 245,
        top: 35,
        scaleX: 0.3,
        scaleY: 0.3,
        clipName: 'pug',
        clipTo: function(ctx) { 
            ctx.save();
            ctx.setTransform(1, 0, 0, 1, 0, 0);
            clipRect1.render(ctx);
            ctx.restore();
        }
    });
    canvas.add(pug);
};
pugImg.src = img02URL;
pugImg.setAttribute('crossOrigin', 'anonymous');
#c {
    border:0px solid #ccc;
}
<script src="//cdn.bootcss.com/fabric.js/1.5.0/fabric.js"></script>
<canvas id="c" width="500" height="400"></canvas>
<a id="download">Download as image</a>

回答1:


Your problem is the multiplier. When using that kind of clipTo functions, you are setting the transform of canvas to plain. When rendering with canvas with multiplier, the base canvas transformation is scaled by the multiplier.

Your rect will be drawn without this transform ( because of setTransform(1,0,0,1,0,0) and will clip out the image.

Instead of setting the transform to [1,0,0,1,0,0] you should set to the invers of the current transformation of the object you are clipping.

var img01URL = 'https://www.google.com/images/srpr/logo4w.png';
var img02URL = 'http://fabricjs.com/lib/pug.jpg';

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

document.getElementById('download').addEventListener('click', function() {
  var data = canvas.toDataURL({
    format: 'png',
    multiplier: 2        
  });
  console.log(data);
  //var img = document.getElementById('export');
  //img.src = data;
}, false);

var clipRect1 = new fabric.Rect({
    originX: 'left',
    originY: 'top',
    angle: 90,
    left: 195,
    top: 0,
    width: 200,
    height: 200,
    fill: '#DDD', /* use transparent for no fill */
    strokeWidth: 1,
    lockMovementX: true,
    lockMovementY: true,
    stroke: 'red',
    angle: 5
});



var pugImg = new Image();
pugImg.onload = function (img) {    
    var pug = new fabric.Image(pugImg, {
        angle: 0,
        width: 500,
        height: 500,
        left: 245,
        top: 35,
        scaleX: 0.3,
        scaleY: 0.3,
        clipName: 'pug',
        clipTo: function(ctx) { 
            ctx.save();
            var myMatrix = this.calcTransformMatrix();
            myMatrix = fabric.util.invertTransform(myMatrix);
            ctx.transform.apply(ctx, myMatrix);
            clipRect1.render(ctx);
            ctx.restore();
        }
    });
    canvas.add(pug);
};
pugImg.src = img02URL;
#c {
    border:0px solid #ccc;
}
<script src="//www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas id="c" width="500" height="400"></canvas>
<a id="download">Download as image</a>
<img id="export" >


来源:https://stackoverflow.com/questions/35716553/fabric-todataurl-with-multiplier-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!