javascript - 平滑缩放 Fabricjs 对象

标签 javascript angularjs canvas fabricjs

我正在使用fabricjs Canvas 库。我找不到fabricjs的动画方法或支持库。

我想做的是放大物体。我不想缩放对象大小。每个对象 Canvas 都会就位。

我想要做的是添加效果,例如相机在放大时聚焦于特定对象,以及当我们缩小时。它将处于初始状态,就像相机移入对象,然后从对象移出到初始状态。

这是我迄今为止尝试过的:

 var jsonData = {"objects":[{"type":"textbox","originX":"left","originY":"top","left":279.36,"top":102.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"First","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20},
 {"type":"textbox","originX":"left","originY":"top","left":100.36,"top":160.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"Second","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20},
 {"type":"textbox","originX":"left","originY":"top","left":10.36,"top":10.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"Third","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20}
 ],"background":""};

        var canvas = new fabric.Canvas('c');
        canvas.loadFromJSON(jsonData, canvas.renderAll.bind(canvas), function(o, object) {
            fabric.log(o, object);
        });

        canvas.on('mouse:down', function(e) {
          console.log(e);
        })
        var canvasScale = 1;
        var SCALE_FACTOR = 1.5;
        var opt = {
          zoomIn : function(zObj){ 
            setTimeout(function(){
              canvas.forEachObject(function(obj){
               
                obj.animate('scaleX', obj.scaleX*SCALE_FACTOR, {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('scaleY', obj.scaleY*SCALE_FACTOR, {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('left', obj.left*SCALE_FACTOR, {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('top', obj.top*SCALE_FACTOR, {duration:3000, onChange: canvas.renderAll.bind(canvas) });
              });
            },1000);
          },
          zoomOut : function(){ 
            setTimeout(function(){
              canvas.forEachObject(function(obj){
                obj.animate('scaleX', '1', {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('scaleY', '1', {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('left', '-=120', {duration:3000, onChange: canvas.renderAll.bind(canvas) });
                obj.animate('left', '-=120', {duration:3000, onChange: canvas.renderAll.bind(canvas) });
              });
            },1000);
          }
        } 

        opt.zoomIn(jsonData.objects[0]);
        setTimeout(function(){
          // opt.zoomOut();

        },10000);
        
        
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.js" integrity="sha256-JYw55W/ryDNiuvQUTPU0zXflTPF/HDlrIXv8+kfP5fM=" crossorigin="anonymous"></script>

<canvas id="c" width="450" height="250" style="width:800px; height:400px; border:2px solid black;"></canvas>  

最佳答案

这里我试图放大特定的对象,因为相机正在聚焦于特定的对象,并且它应该顺利进行。但是,在使用缩放对象时,很难管理特定对象的位置,因为我们永远不知道对象在运行时将放置在哪里。

解决方案:https://jsfiddle.net/cw9k31vy/

 var jsonData = {"objects":[{"type":"textbox","originX":"left","originY":"top","left":279.36,"top":102.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"First","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20},
 {"type":"textbox","originX":"left","originY":"top","left":100.36,"top":160.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"Second","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20},
 {"type":"textbox","originX":"left","originY":"top","left":10.36,"top":10.23,"width":153,"height":29.83,"fill":"#333","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,"scaleX":1.01,"scaleY":1.01,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":1474621288211,"hasControls":false,"objType":"text","attr":"{}","borderColor":"rgba(102,153,255,0.75)","cornerColor":"rgba(102,153,255,0.5)","borderScaleFactor":1,"editable":false,"selectable":true,"text":"Third","fontSize":24,"fontWeight":"normal","fontFamily":"Lato","fontStyle":"","lineHeight":1.1,"textDecoration":"","textAlign":"left","textBackgroundColor":"","styles":{},"minWidth":20}
 ],"background":""};

var canvas = new fabric.Canvas('c');
canvas.loadFromJSON(jsonData, canvas.renderAll.bind(canvas), function(o, object) {
	fabric.log(o, object);
});

canvas.on('mouse:down', function(e) {
  console.log(e);
})
var canvasScale = 1;
var SCALE_FACTOR = 1.5;
 var opt = {
  zoomIn : function(zObj){ 
	setTimeout(function(){
	  var posX = zObj.left+(zObj.width/2);
	  var posY = zObj.top+(zObj.height/2);
	  
	  var zoomCenter = new fabric.Point(posX,posY);
	  var zoomValue = canvas.getZoom() + 0.002;
	  if(zoomValue<1.5){
		canvas.zoomToPoint(zoomCenter, zoomValue);
		canvas.renderAll.bind(canvas)

		opt.zoomIn(zObj)
	  }
	},20);
  },
  zoomOut : function(zObj){ 
	setTimeout(function(){
	  canvas.forEachObject(function(obj){
		var posX = zObj.left+(zObj.width/2);
		var posY = zObj.top+(zObj.height/2);
		
		var zoomCenter = new fabric.Point(posX,posY);
		var zoomValue = canvas.getZoom() -0.002;
		if(zoomValue>1){
		  canvas.zoomToPoint(zoomCenter, zoomValue);
		  canvas.renderAll.bind(canvas)
		  opt.zoomOut(zObj)
		}
	  });
	},20);
  }
} 

opt.zoomIn(jsonData.objects[1]);
setTimeout(function(){
  opt.zoomOut(jsonData.objects[1]);

},10000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js" integrity="sha256-42MK8ODIRAEkCECsfaZOXb2psvEjAD0vK3AL3eNe86w=" crossorigin="anonymous"></script>

<canvas id="c" width="450" height="250" style="width:800px; height:400px; border:2px solid black;"></canvas> 

这里我使用的是 zoomToPoint 方法,该方法工作正常。无需每次都缩放每个对象。

关于javascript - 平滑缩放 Fabricjs 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39640676/

相关文章:

javascript - 下载使用 Express.js 和 Node.js 实现的文档的按钮无法正常工作

javascript - 如何在没有 ng-repeat 的情况下访问数据

javascript - Cropit 将 Canvas 图像上传到 NodeJS

javascript - 在 Canvas 的底部边缘绘画时图案会移动

android - 如何在 Android 中使 Canvas 透明?

javascript - Javascript函数自行调整大小

javascript - highcharts xrange 标签是否只能在适合框时才显示?

javascript - Google App Script - 如何获取指定行的所有值?

javascript - 使用 AngularJS 访问和显示 JSON 对象

javascript - 如何使用 AngularJS 将 JSON 树显示为嵌套 <ul>?