如何将矩形添加到缩放的画布区域?

Posted

技术标签:

【中文标题】如何将矩形添加到缩放的画布区域?【英文标题】:How do I add a rectangle to the zoomed canvas area? 【发布时间】:2021-03-09 08:10:54 【问题描述】:

我正在使用 Fabric JS。每次我按下Add Door 按钮时,它都会在左上角创建。我给了矩形中的值(左:40,上:40,)。 但是,当我在我缩放的区域上按下按钮时,我希望它将它添加到我缩放的区域。我看了几个例子,但找不到我想要的。我该怎么做?

Video

var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('https://i.hizliresim.com/0pIPiv.jpg', canvas.renderAll.bind(canvas));
var uniqids = 0;
$("#door").on("click", function(e) 
  rect = new fabric.Rect(
    id:uniqid,
    left: 40,
    top: 40,
    width: 35,
    height: 50,      
    fill: 'blue',
    stroke: 'blue',
    strokeWidth: 5,
    strokeUniform: false,
    hasControls : true,
  );  

  var uniqid = uniqids.toString(); 

  var text = new fabric.Text(uniqid, 
    fontSize: 30,
    originX: 'center',
    originY: 'right'
  );

  var group = new fabric.Group([ rect, text ], 
    left: 0,
    top: 100,
  );

  canvas.add(group);
  uniqids++;

  canvas.on('selection:cleared', c => 
    console.log("empty");
  );
  canvas.selection = false;

);
//*****************************
// canvas.on('mouse:wheel', function(opt) 
//   var delta = opt.e.deltaY;
//   var zoom = canvas.getZoom();
//   zoom *= 0.999 ** delta;
//   if (zoom > 20) zoom = 20;
//   if (zoom < 0.01) zoom = 0.01;
//   canvas.setZoom(zoom);
//   opt.e.preventDefault();
//   opt.e.stopPropagation();

// )

$('#getid').click(function() 
  var activeObject = canvas.getActiveObjects();
  alert(canvas.getActiveObject().id); 
);



//***************************************

$("#save").on("click", function(e) 
  $(".save").html(canvas.toSVG());
);

$('#delete').click(function() 
  var activeObject = canvas.getActiveObjects(); 
  canvas.discardActiveObject();
  canvas.remove(...activeObject); 
);


$("#btnResetZoom").on("click", function(e) 
  canvas.setViewportTransform([1,0,0,1,0,0]);
);

canvas.on('mouse:wheel', function(opt) 
    var delta = opt.e.deltaY;
    var zoom = canvas.getZoom();
    zoom *= 0.999 ** delta;
    if (zoom > 20) zoom = 20;
    if (zoom < 1) zoom = 1;
    canvas.zoomToPoint(x: opt.e.offsetX, y: opt.e.offsetY, zoom);
    opt.e.preventDefault();
    opt.e.stopPropagation();
);
var shiftKeyDown = true;
var mouseDownPoint = null;
canvas.on('mouse:move', function(options) 
  if (shiftKeyDown && mouseDownPoint) 
    var pointer = canvas.getPointer(options.e, true);
    var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
    canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
    mouseDownPoint = mouseMovePoint;
    keepPositionInBounds(canvas);
  
);




var Direction = 
  LEFT: 0,
  UP: 1,
  RIGHT: 2,
  DOWN: 3
;

var zoomLevel = 0;
var zoomLevelMin = 0;
var zoomLevelMax = 3;

var shiftKeyDown = false;
var mouseDownPoint = null;

canvas.on('mouse:down', function(options) 
  var pointer = canvas.getPointer(options.e, true);
  mouseDownPoint = new fabric.Point(pointer.x, pointer.y);
);
canvas.on('mouse:up', function(options) 
  mouseDownPoint = null;
);
canvas.on('mouse:move', function(options) 
  if (shiftKeyDown && mouseDownPoint) 
    var pointer = canvas.getPointer(options.e, true);
    var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
    canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
    mouseDownPoint = mouseMovePoint;
    keepPositionInBounds(canvas);
  
);
fabric.util.addListener(document.body, 'keydown', function(options) 
  if (options.repeat) 
    return;
  
  var key = options.which || options.keyCode; // key detection
  if (key == 16)  // handle Shift key
    canvas.defaultCursor = 'move';
    canvas.selection = false;
    shiftKeyDown = true;
   else if (key === 37)  // handle Left key
    move(Direction.LEFT);
   else if (key === 38)  // handle Up key
    move(Direction.UP);
   else if (key === 39)  // handle Right key
    move(Direction.RIGHT);
   else if (key === 40)  // handle Down key
    move(Direction.DOWN);
  
);
fabric.util.addListener(document.body, 'keyup', function(options) 
  var key = options.which || options.keyCode; // key detection
  if (key == 16)  // handle Shift key
    canvas.defaultCursor = 'default';
    canvas.selection = true;
    shiftKeyDown = false;
  
);
// jQuery('.canvas-container').on('mousewheel', function(options) 
//   var delta = options.originalEvent.wheelDelta;
//   if (delta != 0) 
//     var pointer = canvas.getPointer(options.e, true);
//     var point = new fabric.Point(pointer.x, pointer.y);
//     if (delta > 0) 
//       zoomIn(point);
//      else if (delta < 0) 
//       zoomOut(point);
//     
//   
// );

function move(direction) 
  switch (direction) 
    case Direction.LEFT:
      canvas.relativePan(new fabric.Point(-10 * canvas.getZoom(), 0));
      break;
    case Direction.UP:
      canvas.relativePan(new fabric.Point(0, -10 * canvas.getZoom()));
      break;
    case Direction.RIGHT:
      canvas.relativePan(new fabric.Point(10 * canvas.getZoom(), 0));
      break;
    case Direction.DOWN:
      canvas.relativePan(new fabric.Point(0, 10 * canvas.getZoom()));
      break;
  
  keepPositionInBounds(canvas);



// function zoomIn(point) 
//   if (zoomLevel < zoomLevelMax) 
//     zoomLevel++;
//     canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
//     keepPositionInBounds(canvas);
//   
// 

// function zoomOut(point) 
//   console.log(zoomLevel, zoomLevelMin);
//   if (zoomLevel > zoomLevelMin) 
//     zoomLevel--;
//     canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
//     keepPositionInBounds(canvas);
//   
// 

function keepPositionInBounds() 
  var zoom = canvas.getZoom();
  var xMin = (2 - zoom) * canvas.getWidth() / 2;
  var xMax = zoom * canvas.getWidth() / 2;
  var yMin = (2 - zoom) * canvas.getHeight() / 2;
  var yMax = zoom * canvas.getHeight() / 2;

  var point = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2);
  var center = fabric.util.transformPoint(point, canvas.viewportTransform);

  var clampedCenterX = clamp(center.x, xMin, xMax);
  var clampedCenterY = clamp(center.y, yMin, yMax);

  var diffX = clampedCenterX - center.x;
  var diffY = clampedCenterY - center.y;

  if (diffX != 0 || diffY != 0) 
    canvas.relativePan(new fabric.Point(diffX, diffY));
  


function clamp(value, min, max) 
  return Math.max(min, Math.min(value, max));
#c 
  background-color: grey;
  margin-top: 10px;


button 
  padding: 10px 20px;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<button id="door">Door</button>
<button id="delete">Delete Door</button>
<button id="save">Save</button>
<button id="getid">GET ID</button>
<button id="btnResetZoom">Reset Zoom</button>

<canvas id="c"  ></canvas>
<br>  
<p class="save">
</p>

【问题讨论】:

【参考方案1】:

我认为你应该使用transformPoint方法来翻译位置

    $("#door").on("click", function (e) 
    const points = ;
    const iVpt = fabric.util.invertTransform(canvas.viewportTransform);
    points.tl = fabric.util.transformPoint(x: 40, y: 40, iVpt);
    rect = new fabric.Rect(
        id: uniqid,
        left: points.tl.x,
        top: points.tl.y,
        width: 35,
        height: 50,
        fill: "blue",
        stroke: "blue",
        strokeWidth: 5,
        strokeUniform: false,
        hasControls: true,
    );

【讨论】:

以上是关于如何将矩形添加到缩放的画布区域?的主要内容,如果未能解决你的问题,请参考以下文章

缩放并旋转JavaFX画布的某个区域

JS中canvas画布绘制中如何实现缩放,位移,旋转

如何仅使用 HTML5 功能使画布移动?

画布 canvas 的相关内容

如何在 html 画布中获取动画方向?

如何计算偏移量以绘制到画布中应用了比例变换的最近像素?