add path select
This commit is contained in:
parent
49bc739f8c
commit
84de3f9a27
@ -39,7 +39,7 @@
|
|||||||
<div id="control-point" class="point" data-index="2"></div>
|
<div id="control-point" class="point" data-index="2"></div>
|
||||||
<div class="point" data-index="3"></div>
|
<div class="point" data-index="3"></div>
|
||||||
<div class="point" data-index="4"></div>
|
<div class="point" data-index="4"></div>
|
||||||
<canvas id="canvas" width="500" height="500"></canvas>
|
<canvas id="canvas" width="800" height="800"></canvas>
|
||||||
<script>
|
<script>
|
||||||
require.config({
|
require.config({
|
||||||
baseUrl: '../src',
|
baseUrl: '../src',
|
||||||
|
@ -22,13 +22,7 @@ define(
|
|||||||
var width = canvas.offsetWidth;
|
var width = canvas.offsetWidth;
|
||||||
var height = canvas.offsetHeight;
|
var height = canvas.offsetHeight;
|
||||||
|
|
||||||
var points = [
|
var points = [{"x":231,"y":609},{"x":231,"y":558},{"x":300,"y":516},{"x":299,"y":591},{"x":299,"y":600}];
|
||||||
{"x":163,"y":136},
|
|
||||||
{"x":45,"y":54},
|
|
||||||
{"x":124,"y":177},
|
|
||||||
{"x":222,"y":122},
|
|
||||||
{"x":57,"y":122}
|
|
||||||
];
|
|
||||||
|
|
||||||
$('[data-index]').each(function(index, item) {
|
$('[data-index]').each(function(index, item) {
|
||||||
$(item).css({
|
$(item).css({
|
||||||
|
@ -82,7 +82,7 @@ define(
|
|||||||
var computeBoundingBox = require('graphics/computeBoundingBox');
|
var computeBoundingBox = require('graphics/computeBoundingBox');
|
||||||
var pathAdjust = require('render/util/pathAdjust');
|
var pathAdjust = require('render/util/pathAdjust');
|
||||||
|
|
||||||
pathArray.slice(4, 5).forEach(function(path) {
|
pathArray.forEach(function(path) {
|
||||||
var shape = {};
|
var shape = {};
|
||||||
shape.points = path;
|
shape.points = path;
|
||||||
var bound = computeBoundingBox.computePath(path);
|
var bound = computeBoundingBox.computePath(path);
|
||||||
@ -96,17 +96,7 @@ define(
|
|||||||
pathPanel.addShape('path', shape);
|
pathPanel.addShape('path', shape);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
currentRender.refresh();
|
currentRender.refresh();
|
||||||
|
|
||||||
// cover.removeShape(0);
|
|
||||||
// cover.removeShape(shape1);
|
|
||||||
// cover.removeShape(shape2.id);
|
|
||||||
|
|
||||||
// currentRender.removeLayer('cover');
|
|
||||||
// currentRender.removeLayer(font);
|
|
||||||
|
|
||||||
//currentRender.dispose();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ define(
|
|||||||
*/
|
*/
|
||||||
function isBezierSegmentCross(p0, p1, p2, s0, s1) {
|
function isBezierSegmentCross(p0, p1, p2, s0, s1) {
|
||||||
var b1 = computeBoundingBox.quadraticBezier(p0, p1, p2);
|
var b1 = computeBoundingBox.quadraticBezier(p0, p1, p2);
|
||||||
|
var isPointInBound = require('./util').isPointInBound;
|
||||||
var bound = {
|
var bound = {
|
||||||
x: Math.min(s0.x, s1.x),
|
x: Math.min(s0.x, s1.x),
|
||||||
y: Math.min(s0.y, s1.y),
|
y: Math.min(s0.y, s1.y),
|
||||||
@ -36,8 +37,7 @@ define(
|
|||||||
var result = isBezierLineCross(p0, p1, p2, s0, s1);
|
var result = isBezierLineCross(p0, p1, p2, s0, s1);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result.filter(function(p) {
|
return result.filter(function(p) {
|
||||||
return p.x >= s0.x && p.x <= s1.x
|
return isPointInBound(bound, p, true);
|
||||||
|| p.x >= s1.x && p.x <= s0.x;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
139
src/graphics/isPathCross.js
Normal file
139
src/graphics/isPathCross.js
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* @file isPathCross.js
|
||||||
|
* @author mengke01
|
||||||
|
* @date
|
||||||
|
* @description
|
||||||
|
* 判断路径的包含关系
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
function(require) {
|
||||||
|
var computeBoundingBox = require('./computeBoundingBox');
|
||||||
|
var isSegmentCross = require('./isSegmentCross');
|
||||||
|
var isBezierCross = require('./isBezierCross');
|
||||||
|
var isBezierSegmentCross = require('./isBezierSegmentCross');
|
||||||
|
var isInsidePath = require('./isInsidePath');
|
||||||
|
var isBoundingBoxCross = require('./isBoundingBoxCross');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 求两个路径的交点集合
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function getJoint(path, command, p0, p1, p2) {
|
||||||
|
|
||||||
|
var i = -1;
|
||||||
|
var l = path.length;
|
||||||
|
var prev, point;
|
||||||
|
var joint = [];
|
||||||
|
var result;
|
||||||
|
|
||||||
|
while (++i < l) {
|
||||||
|
|
||||||
|
result = false;
|
||||||
|
point = path[i];
|
||||||
|
|
||||||
|
switch (point.c) {
|
||||||
|
case 'L':
|
||||||
|
if (command == 'L') {
|
||||||
|
result = isSegmentCross(p0, p1, prev, point.p);
|
||||||
|
}
|
||||||
|
else if (command == 'Q') {
|
||||||
|
result = isBezierSegmentCross(p0, p1, p2, prev, point.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(result) {
|
||||||
|
// console.log(p0, p1, p2, prev, point.p);
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
if (command == 'L') {
|
||||||
|
result = isBezierSegmentCross(
|
||||||
|
prev, point.p1, point.p, p0, p1);
|
||||||
|
}
|
||||||
|
else if (command == 'Q') {
|
||||||
|
result = isBezierCross(prev, point.p1, point.p, p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(result) {
|
||||||
|
// console.log(prev, point.p1, point.p, p0, p1, p2);
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
joint = joint.concat(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = point.p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return joint.length ? joint : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 求两个路径的交点集合
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function getPathJoint(path0, path1) {
|
||||||
|
|
||||||
|
var i = -1;
|
||||||
|
var l = path0.length;
|
||||||
|
var prev, point;
|
||||||
|
var joint = [];
|
||||||
|
var result;
|
||||||
|
|
||||||
|
while (++i < l) {
|
||||||
|
result = false;
|
||||||
|
point = path0[i];
|
||||||
|
switch (point.c) {
|
||||||
|
case 'L':
|
||||||
|
result = getJoint(path1, 'L', prev, point.p);
|
||||||
|
break;
|
||||||
|
case 'Q':
|
||||||
|
result = getJoint(path1, 'Q', prev, point.p1, point.p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
joint = joint.concat(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev = point.p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return joint.length ? joint : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断x轴射线是否穿过线段
|
||||||
|
*
|
||||||
|
* @return {boolean|Array} 是否, 或者包含数组
|
||||||
|
*/
|
||||||
|
function isPathCross(path0, path1, bound0, bound1) {
|
||||||
|
bound0 = bound0 || computeBoundingBox.computePath(path0);
|
||||||
|
bound1 = bound1 || computeBoundingBox.computePath(path1);
|
||||||
|
var boundCross = isBoundingBoxCross(bound0, bound1);
|
||||||
|
|
||||||
|
if (boundCross) {
|
||||||
|
var result = getPathJoint(path0, path1);
|
||||||
|
if (!result) {
|
||||||
|
// 0 包含 1
|
||||||
|
if (isInsidePath(path1, path0[0].p)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
// 1 包含 0
|
||||||
|
else if(isInsidePath(path0, path1[0].p)) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPathCross;
|
||||||
|
}
|
||||||
|
);
|
@ -10,6 +10,7 @@
|
|||||||
define(
|
define(
|
||||||
function(require) {
|
function(require) {
|
||||||
var lang = require('common/lang');
|
var lang = require('common/lang');
|
||||||
|
var selectShape = require('./util/selectShape');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化
|
* 初始化
|
||||||
@ -31,10 +32,15 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
render.capture.on('down', function(e) {
|
render.capture.on('down', function(e) {
|
||||||
var shape = render.painter.getShapeIn(e);
|
var result = render.painter.getShapeIn(e);
|
||||||
|
|
||||||
if(shape) {
|
if(result) {
|
||||||
render.selectedShape = shape;
|
if (result.length > 1) {
|
||||||
|
render.selectedShape = selectShape(result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
render.selectedShape = result[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
render.camera.mx = e.x;
|
render.camera.mx = e.x;
|
||||||
render.camera.my = e.y;
|
render.camera.my = e.y;
|
||||||
|
@ -204,11 +204,13 @@ define(
|
|||||||
getShapeIn: function(p) {
|
getShapeIn: function(p) {
|
||||||
var support = this.painter.support;
|
var support = this.painter.support;
|
||||||
var shapes = this.shapes;
|
var shapes = this.shapes;
|
||||||
|
var result = [];
|
||||||
for(var i = 0, l = shapes.length; i < l; i++) {
|
for(var i = 0, l = shapes.length; i < l; i++) {
|
||||||
if (support[shapes[i].type].isIn(shapes[i], p.x, p.y)) {
|
if (support[shapes[i].type].isIn(shapes[i], p.x, p.y)) {
|
||||||
return shapes[i];
|
result.push(shapes[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result.length ? result : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
64
src/render/util/selectShape.js
Normal file
64
src/render/util/selectShape.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* @file selectShape.js
|
||||||
|
* @author mengke01
|
||||||
|
* @date
|
||||||
|
* @description
|
||||||
|
* 从待选的shape中选择一个,作为选中的shape
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
define(
|
||||||
|
function(require) {
|
||||||
|
var lang = require('common/lang');
|
||||||
|
var computeBoundingBox = require('../../graphics/computeBoundingBox');
|
||||||
|
var isPathCross = require('../../graphics/isPathCross');
|
||||||
|
var pathAdjust = require('./pathAdjust');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从待选的shape中选择一个,作为选中的shape
|
||||||
|
*
|
||||||
|
* @return {Object} selected shape
|
||||||
|
*/
|
||||||
|
function selectShape(shapes) {
|
||||||
|
|
||||||
|
if (shapes.length == 1) {
|
||||||
|
return shapes[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var sorted = shapes.map(function(shape) {
|
||||||
|
var bound = computeBoundingBox.computePath(shape.points);
|
||||||
|
bound.x = shape.x;
|
||||||
|
bound.y = shape.y;
|
||||||
|
shape._bound = bound;
|
||||||
|
shape._size = bound.width * bound.height;
|
||||||
|
return shape;
|
||||||
|
}).sort(function (a, b) {
|
||||||
|
return a._size - b._size;
|
||||||
|
});
|
||||||
|
|
||||||
|
var start = sorted[0];
|
||||||
|
var end = sorted[sorted.length - 1];
|
||||||
|
|
||||||
|
var startPoints = pathAdjust(lang.clone(start.points), 1, start.x, start.y);
|
||||||
|
var endPoints = pathAdjust(lang.clone(end.points), 1, end.x, end.y);
|
||||||
|
|
||||||
|
var result = isPathCross(
|
||||||
|
startPoints, endPoints,
|
||||||
|
start._bound, end._bound
|
||||||
|
);
|
||||||
|
|
||||||
|
if(2 === result) {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
else if(3 === result) {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return shapes[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectShape;
|
||||||
|
}
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user