Fabric.js相对于getZoom()和getWidth()/ getHeight()的位置元素 [英] Fabric.js position elements relative to getZoom() and getWidth()/getHeight()

查看:474
本文介绍了Fabric.js相对于getZoom()和getWidth()/ getHeight()的位置元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有React / Redux的Fabric.js,我试图在画布上实现以下效果:(注意我在顶部和左侧有两个标尺,在平移时只能水平和垂直移动) 。



这是我想要获得的效果的视频:



以下是两个缩放功能:

  / * ZOOM FUNCTIONS * / 
$('#zoomIn')。click(function(){
rectangle.set({
width:rectangle.width * 1.1,
height:rectangle.height * 1.1
});
rectangle.setCoords();
textSample.set({
顶部:60 +(textSample.top - 60)* 1.1,
左:60 +(textSample.left - 60)* 1.1,
scaleX:textSample.scaleX * 1.1,
scaleY: textSample.scaleY * 1.1
});
textSample.setCoords();
setPins();
addLeftRuler();
addTopRuler();
resizeCanvas();
});
$('#zoomOut')。click(function(){
rectangle.set({
width:rectangle.width / 1.1,
height:rectangle.height / 1.1
});
rectangle.setCoords();
textSample.set({
top:60 +(textSample.top - 60)/ 1.1,
left: 60 +(textSample.left - 60)/ 1.1,
scaleX:textSample.scaleX / 1.1,
scaleY:textSample.scaleY / 1.1
})
textSample.setCoords() ;
setPins();
addLeftRuler();
addTopRuler();
resizeCanvas();
});

使用第三方控件和传统方式完成平移,因为这是视频显示的内容(你想要的) - 当滚动发生时,通过更新它们的位置来保持顶部和左边的标尺。



通过基于点缩放单个对象来完成缩放(60 ,60) - 如在视频中。引脚被重置,标尺被重新调整,并且画布被调整大小 - 根据需要。



诀窍在于计算并重新计算所有内容,因为用户操作被采取并且事件正在被触发。



希望这能为你提供你需要构建的画布基础。



这是一个有效的JSFiddle, https://jsfiddle.net/rekrah/hs6jL8d4/


I am using Fabric.js with React/Redux and i am trying to achieve the following effect on canvas: (note i have 2 rulers on the top and left which shouldn't move around when panning, just horizontally and vertically).

This is a video of the effect I am trying to get: https://vid.me/qs5Q

I have the following code:

var canvas = new fabric.Canvas('c');
var topRuler = new fabric.Text('this is the top ruler', {
  top: 0,
  left: 60,
  selectable: false
});
var leftRuler = new fabric.Text('this is the left ruler', {
  top: 150,
  left: -125,
  selectable: false
});
var circle = new fabric.Circle({
  radius: 20,
  fill: 'green',
  left: 180,
  top: 100
});
var triangle = new fabric.Triangle({
  fill: 'green',
  left: 150,
  top: 170
});
var panning = false;
var panningOn = false;
leftRuler.setAngle(-90).setCoords();
canvas.add(circle, triangle, topRuler, leftRuler);
canvas.renderAll();

canvas.on('mouse:up', function(e) {
 if (panningOn) panning = false;
});

canvas.on('mouse:down', function(e) {
 if (panningOn) panning = true;
});

canvas.on('mouse:move', function(e) {
  if (panning && e && e.e) {
  moveX = e.e.movementX;
  moveY = e.e.movementY;
  topRuler.set({
    top: topRuler.top - moveY,
    left: topRuler.left - moveX
  });

  leftRuler.set({
    top: leftRuler.top - moveY,
    left: leftRuler.left - moveX
  });
   canvas.relativePan(new fabric.Point(moveX, moveY));
  }
});
$('#toggle').click(function() {
  panningOn = !panningOn;
  canvas.selection = !panningOn;
  canvas.defaultCursor = 'default';
  $('#toggle').html('Turn Panning ON');
  if (panningOn) {
   $('#toggle').html('Turn Panning OFF');
   canvas.defaultCursor = 'move';
  }
});

 /* ZOOM FUNCTIONS */
 $('#zoomIn').click(function(){
    canvas.setZoom(canvas.getZoom() * 1.1 ) ;
 });

 $('#zoomOut').click(function(){
    canvas.setZoom(canvas.getZoom() / 1.1 ) ;
 });

This is a working JSFiddle: https://jsfiddle.net/z3p8utmc/19/ The code is not complete since I do not know exactly how to position the rulers, tried to play with viewPort, canvas size, etc. but did not manage to get the same effect.

Thank you for the help.

解决方案

Here's a screen shot of the results:

Here's the two zoom functions:

/* ZOOM FUNCTIONS */
$('#zoomIn').click(function() {
  rectangle.set({
    width: rectangle.width * 1.1,
    height: rectangle.height * 1.1
  });
  rectangle.setCoords();
  textSample.set({
    top: 60 + (textSample.top - 60) * 1.1,
    left: 60 + (textSample.left - 60) * 1.1,
    scaleX: textSample.scaleX * 1.1,
    scaleY: textSample.scaleY * 1.1
  });
  textSample.setCoords();
  setPins();
  addLeftRuler();
  addTopRuler();
  resizeCanvas();
});
$('#zoomOut').click(function() {
  rectangle.set({
    width: rectangle.width / 1.1,
    height: rectangle.height / 1.1
  });
  rectangle.setCoords();
  textSample.set({
    top: 60 + (textSample.top - 60) / 1.1,
    left: 60 + (textSample.left - 60) / 1.1,
    scaleX: textSample.scaleX / 1.1,
    scaleY: textSample.scaleY / 1.1
  })
  textSample.setCoords();
  setPins();
  addLeftRuler();
  addTopRuler();
  resizeCanvas();
});

Panning is done using a 3rd-Party control, and the traditional way, since that's what the video shows (and you wanted) - top and left rulers are kept in place by updating their positions as scrolling occurs.

Zooming is done by scaling the individual objects based on point (60, 60) - as in the video. Pins are reset, rulers are rescaled, and canvas is resized - as needed.

The trick is calculating and recalculating everything as user actions are taken and events are firing.

Hopefully this gets you the canvas foundation you need to build upon.

Here's a working JSFiddle, https://jsfiddle.net/rekrah/hs6jL8d4/.

这篇关于Fabric.js相对于getZoom()和getWidth()/ getHeight()的位置元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆