对象捕捉到Fabric.js上的客户网格

Objects snap to custum grid on fabric.js(对象捕捉到Fabric.js上的客户网格)

本文介绍了对象捕捉到Fabric.js上的客户网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个应用程序,我需要在MouseMove上将对象捕捉到一个网格,但我不需要一个常规的网格,而是一个自定义的网格。我找到了这个Fiddle,并试图放置我自己的栅格,但对象没有捕捉到它。我需要的是对象的中心,以便捕捉到由两条网格线形成的十字。

这是我的代码: 数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">

var canvas = new fabric.Canvas('c', { selection: false });
var grid = 20;

// create grid

for (var i = 0; i < (canvas.height / grid); i++) {
  canvas.add(new fabric.Path('m 260.75,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 309.75,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 353.75,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 391.25,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 419.25,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 435.25,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 216.5,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 179,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 151,122.82188 0,349.31925', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 135,122.82188 0,349.31925 ', { stroke: '#ccc', selectable: false }));

  canvas.add(new fabric.Path('m 110.91682,147.25 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,161.25 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,188 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,224.75 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,269.75 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,326.05147 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,370.83102 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,407.75 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,434.25 348.63852,0', { stroke: '#ccc', selectable: false }));
  canvas.add(new fabric.Path('m 110.91682,448.5 348.63852,0', { stroke: '#ccc', selectable: false }));
}

// add objects

canvas.add(new fabric.Rect({
  left: 100,
  top: 100,
  width: 20,
  height: 20,
  fill: '#faa',
  originX: 'center',  originY: 'center',
  centeredRotation: true
}));

// snap to grid

canvas.on('object:moving', function(options) { 
  options.target.set({
    left: Math.round(options.target.left / grid) * grid,
    top: Math.round(options.target.top / grid) * grid
  });
});
<html>
<head>
<script src="aHR0cHM6Ly9yYXdnaXRodWIuY29tL2thbmdheC9mYWJyaWMuanMvbWFzdGVyL2Rpc3QvZmFicmljLmpz"></script>


</head>
<body>
<canvas id="c" width="600" height="600"></canvas>

如果有人能帮上忙,我们将予以欢迎。

再次分析后,我发现SVG正在捕捉到varvar grid = 20;中可能给出的网格,但不是我使用canvas.add(new fabric.Path('m 110.91682,147.25 348.63852,0', { stroke: '#ccc', selectable: false }));创建的网格。这很可能是罪魁祸首,但我不确定。

推荐答案

确实是var grid = 20导致您的问题,因为您的网格间距不同。您已经静态创建了网格,但是使用定义起点和间距的对象会更加动态,并允许您使用相同的对象将事件捕捉到动态创建的网格点。

我可以使用网格间距对象数组,并使用x和的数组实例化开始和坐标对象,将线条放入每个坐标键下的坐标对象中。

坐标对象实际上是从起始位置开始的每行之间的空格。开始对象是在xy轴上绘制的线条边缘的开始位置。

我们将使用这些对象动态创建网格和一个对象以供稍后用于捕捉鼠标的引用移动到网格。

使用gridSpacing[0]['start']['x']gridSpacing[0]['start']['y']定义起点。然后使用两个数组来保存动态创建的x轴线y轴线-xArryArr的值。

然后创建嵌套的for循环,在xArryarr上循环以创建对象。

另外两个for循环使用xArr*和yarr数组动态创建网格。

最后是object:moving事件中的捕捉部分。实例化将保存the event.target.leftevent.target.top属性作为键/值对的轴对象。我们使用它来迭代Points对象,并使用条件来检查鼠标移动事件相对于x轴相对于x轴点对象键/值的位置。

数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
var canvas = new fabric.Canvas('c', {
  selection: false
});

// insantiate object for starting and coordinates of spacing
const gridSpacing = [{
  start: {
    x: 111,
    y: 123.25
  },
  coords: {
    x: [24, 16, 28, 37.5, 44.25, 49, 44, 37.5, 28, 16],
    y: [24, 16, 28, 37.5, 44.25, 49, 44, 37.5, 28, 16]
  }
}]

// create grid

// define the starting coords
let xCoords = gridSpacing[0]['start']['x'];
let yCoords = gridSpacing[0]['start']['y'];

// instantiate x axis and y axis arrays
let xArr = []
let yArr = []

// fill xArr with values using gridSpacing object
for (let x = 0; x < gridSpacing[0].coords['x'].length; x++) {
  let spacing = gridSpacing[0].coords['x'][x]
  xArr.push(xCoords += spacing)
}
// fill yArr with values using gridSpacing object
for (let y = 0; y < gridSpacing[0].coords['y'].length; y++) {
  let spacing = gridSpacing[0].coords['y'][y]
  yArr.push(yCoords += spacing)
}
// instantiate points obj using xArr and yArr for in loops
const points = []
for (let i in xArr) {
  for (let y in yArr) {
    points.push({
      [xArr[i]]: yArr[y]
    })
  }
}

/* EDIT: This is the section that draws the grid lines. No need for it as you are using the points object and xArr and yArr to make your mouse snap to the spacing. 

// create and draw x axis grid dynamically using xArr
for (let x = 0; x < xArr.length; x++) {
  canvas.add(new fabric.Path(`m ${xArr[x]},122.82188 0,349.31925`, {
    stroke: '#ccc',
    selectable: false
  }));
}
// create and draw y axis grid dynamically using yArr
for (let y = 0; y < gridSpacing[0].coords['y'].length; y++) {
  canvas.add(new fabric.Path(`m 110.91682,${yArr[y]} 348.63852,0`, {
    stroke: '#ccc',
    selectable: false
  }));
}
*/

// add objects

canvas.add(new fabric.Rect({
  left: 100,
  top: 100,
  width: 20,
  height: 20,
  fill: '#faa',
  originX: 'center',
  originY: 'center',
  centeredRotation: true
}));

canvas.add(new fabric.Circle({
  left: xArr[5],
  top: yArr[5],
  radius: 60,
  fill: '#9f9',
  originX: 'center',
  originY: 'center',
  centeredRotation: true
}));

// snap to grid

canvas.on('object:moving', function(event) {
  // create objbect that will hold current mouse move events x and y
  let axis = {
    [event.target.left]: event.target.top
  }  
  let x, y = '';
  // iterate over our points and check event.target values
  points.forEach((point, i) => {
    // conditional to check x axis boundaries and point variations
    // left
    if (parseInt(Object.keys(axis)) < xArr[1] - xArr[1] * .1 || parseInt(Object.keys(axis)) < xArr[0]) {
      x = xArr[0]
    // right
    }else if (parseInt(Object.keys(axis)) > xArr[xArr.length - 1]) {
      x = xArr[xArr.length - 1]
    // boundaries
    }else if (Object.keys(axis) < Object.keys(points[i]) && Object.keys(axis) > Object.keys(points[i - 1]) && Object.keys(axis) > xArr[0]) {
      x = Object.keys(points[i])
    }
    
    // conditional to check y axis boundaries and point variations
    // up
    if (parseInt(Object.values(axis)) < yArr[1] - yArr[1] * .1 || parseInt(Object.values(axis)) < yArr[0]) {
      y = yArr[0]
    // down
    }else if (parseInt(Object.values(axis)) > yArr[yArr.length - 1]) {
      y = yArr[yArr.length - 1]
      // boundaries
    }else if (Object.values(axis) < Object.values(points[i]) && Object.values(axis) > Object.values(points[i - 1]) && Object.values(axis) > xArr[0]) {
      y = Object.values(points[i])
    }
  }) 
  // set event.target left and top properties
  event.target.set({
    left: parseInt(x),
    top: parseInt(y)
  })
})
<html>

<head>
  <script src="aHR0cHM6Ly9yYXdnaXRodWIuY29tL2thbmdheC9mYWJyaWMuanMvbWFzdGVyL2Rpc3QvZmFicmljLmpz"></script>


</head>

<body>
  <canvas id="c" width="600" height="600"></canvas>
</body>

这篇关于对象捕捉到Fabric.js上的客户网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:对象捕捉到Fabric.js上的客户网格