Objects snap to custum grid on 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="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></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和的数组实例化开始和坐标对象,将线条放入每个坐标键下的坐标对象中。
坐标对象实际上是从起始位置开始的每行之间的空格。开始对象是在x和y轴上绘制的线条边缘的开始位置。
我们将使用这些对象动态创建网格和一个点对象以供稍后用于捕捉鼠标的引用移动到网格。
使用gridSpacing[0]['start']['x']和gridSpacing[0]['start']['y']定义起点。然后使用两个数组来保存动态创建的x轴线和y轴线-xArr和yArr的值。
然后创建嵌套的for循环,在xArr和yarr上循环以创建点对象。
另外两个for循环使用xArr*和yarr数组动态创建网格。
最后是object:moving事件中的捕捉部分。实例化将保存the event.target.left和event.target.top属性作为键/值对的轴对象。我们使用它来迭代Points对象,并使用条件来检查鼠标移动事件相对于x轴和值相对于x轴和点对象键/值的位置。
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="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
</head>
<body>
<canvas id="c" width="600" height="600"></canvas>
</body>
这篇关于对象捕捉到Fabric.js上的客户网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:对象捕捉到Fabric.js上的客户网格
基础教程推荐
- 即使每次插入第一个输入的值不同,第二个输入仍显示相同的输入值 2022-01-01
- 逻辑运算符 ||在 javascript 中,0 代表 Boolean false? 2022-01-01
- HTML5 画布调整为父级 2022-01-01
- 在 Javascript 中使用 Fetch API 上传文件并显示进度 2022-01-01
- 从快速中间件中排除路由 2022-01-01
- 最佳动态 JavaScript/JQuery 网格 2022-01-01
- 使用 jQuery 在悬停时交换 DIV 类 2022-01-01
- 带角度的选项卡:仅使用 $http 在单击时加载选项卡 2022-01-01
- 当木偶师打开Chrome时,不能使用Chrome扩展 2022-01-01
- CORS:当凭据标志为真时,无法在 Access-Control-Allow-Origin 中使用通配符 2022-01-01
