如何在Fabricjs中以百分比存储绘图矩形坐标

时间:2017-06-12 10:19:47

标签: javascript fabricjs

在我的项目中,我正致力于在特定建筑物的楼层创建和删除动态区域。要做到这一点,将使用Raphealjs,使用rapheal我能够在地板上创建区域。我正在为数据库存储高度,宽度,startx和stary。

但问题是,它以像素为单位存储坐标。当我将屏幕缩小时,该区域会从我的地板上移开。解决方案我需要以百分比存储坐标。

有没有办法做,请帮我出来。

下面是我的图片,它显示的是清晰的图片。

小屏幕时:

请给我解决方案,提前致谢..

1 个答案:

答案 0 :(得分:0)

您是否尝试在缩小屏幕尺寸时缩小/缩小布料对象?我的建议是存储一个逻辑点。例如,您的画布大小为500x600像素,并且您在位置x = 100,y = 100,宽度= 50和高度= 50时具有矩形。逻辑坐标将是您的实际坐标(以像素为单位)除以画布的尺寸。换句话说,你的

logicalX = x/canvas.width (100/500=0.2)
logicalY = y/canvas.height (100/600=0.16666666666666)
width = width/canvas.width (50/500=0.1)
height = height/canvas.height (50/600=0.833333)

在这种情况下,您将拥有动态坐标,即使您将使用与上一个会话不同的画布大小加载您的应用程序。无论何时,只要您调整画布大小,就应该重新计算物理点并再次渲染所有画布。您可以将逻辑坐标对象分配给fabricjs对象:

var rect1 = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'green',
  width: 50,
  height: 50,
  id : someid,
  logicalCoords: {x: 0.2,
                  y: 0.16666666666666,
                  width: 0.1,
                  height: 0.833333}
  });

重新计算物理点很容易,你应该遍历所有的fabricjs对象并将你的画布尺寸乘以逻辑点:

canvas.forEachObject(function(o){ 
   o.x = logicalCoords.x * canvas.width;
   o.x = logicalCoords.y * canvas.height;
   o.x = logicalCoords.width * canvas.width;
   o.x = logicalCoords.height * canvas.height;
});
canvas.renderAll();

警告:它不是正常工作的代码,它只是一个想法如何解决您的问题。

更新1: Fabricjs需要像素数据来绘制形状。你可以这样做:

var rect1 = new fabric.Rect({
      left: toPixels(percentValueLeftFromDB),
      top: toPixels(percentValueTopFromDB),
      fill: 'green',
      width: toPixels(percentValueWidthFromDB),
      height: toPixels(percentValueHeightFromDB),
      });
function toPixels(value){
//do conversion here..
//you should take care of left and top coordinates
pixelValue = canvas.width * value / 100; //calculates only width and top 
return pixelValue;

没有像百分比这样的自动化。你必须自己做转换。我向您展示了物理点的2个变化逻辑点,或物理点的百分比点数。您需要将物理点路径连接到Fabricjs。在我看来,逻辑点比百分比更准确。

更新2:

为什么逻辑点会响应,因为它需要所有时间的查看器大小。例如,正如您在评论中提到的不同物理屏幕尺寸(以英寸为单位),您将拥有不同的屏幕分辨率。理想情况下,每个分辨率都有动态画布大小,可以动态计算或在CSS中设置为百分比。我们假设您为画布设置width = 75%和height = 60%。如果您将在不同的屏幕或设备上打开此画布,则画布的物理宽度和高度将以不同为单位。在这种情况下,logicalPoint将位于每个设备上的相同位置,因为您需要使用画布尺寸将它们转换为physicalPoint。 假设您的画布尺寸为1000x500像素,您的矩形具有逻辑(顶部,左侧)坐标(0.5,0.5),宽度= 0.5,高度= 0.5。物理结果将是位置(500,250)的矩形,宽度= 500,高度= 250.如果您将采用相同的逻辑坐标,尝试在较小的画布上显示它们,它将是矩形的相同位置。

请检查这个简单的fiddle,它显示了2幅画布的逻辑协调。

注意: 只有在您使用相同的宽高比保持画布大小时,此逻辑才有效。如果要将画布宽度调整50%,则必须将高度调整50%。

此外,小提琴代码在这里:

HTML:

<canvas id="canvas1" width="200" height="150"  style="border:1px solid #ccc"></canvas>
<canvas id="canvas2" width="400" height="350"  style="border:1px solid #ccc"></canvas>

JavaScript的:

(function() {
    var canvas1 = this.__canvas = new fabric.Canvas('canvas1');
    var canvas2 = this.__canvas = new fabric.Canvas('canvas2');

    var rect = new fabric.Rect({
       left: logicalToPhysical(0.5, canvas1.width),
       top: logicalToPhysical(0.5, canvas1.height),
       width: logicalToPhysical(0.5, canvas1.width),
       height: logicalToPhysical(0.5, canvas1.height),
       fill: 'rgba(255,127,39,1)'
    });
    canvas1.add(rect);
    canvas1.renderAll();

    var rect = new fabric.Rect({
       left: logicalToPhysical(0.5, canvas2.width),
       top: logicalToPhysical(0.5, canvas2.height),
       width: logicalToPhysical(0.5, canvas2.width),
       height: logicalToPhysical(0.5, canvas2.height),
       fill: 'rgba(255,127,39,1)'
    });
    canvas2.add(rect);
    canvas2.renderAll();
})();

function logicalToPhysical(value, dimension){
    return value * dimension;
}