add path select

This commit is contained in:
kekee000 2014-09-08 23:30:23 +08:00
parent 49bc739f8c
commit 84de3f9a27
8 changed files with 221 additions and 26 deletions

View File

@ -39,7 +39,7 @@
<div id="control-point" class="point" data-index="2"></div>
<div class="point" data-index="3"></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>
require.config({
baseUrl: '../src',

View File

@ -22,13 +22,7 @@ define(
var width = canvas.offsetWidth;
var height = canvas.offsetHeight;
var points = [
{"x":163,"y":136},
{"x":45,"y":54},
{"x":124,"y":177},
{"x":222,"y":122},
{"x":57,"y":122}
];
var points = [{"x":231,"y":609},{"x":231,"y":558},{"x":300,"y":516},{"x":299,"y":591},{"x":299,"y":600}];
$('[data-index]').each(function(index, item) {
$(item).css({

View File

@ -82,7 +82,7 @@ define(
var computeBoundingBox = require('graphics/computeBoundingBox');
var pathAdjust = require('render/util/pathAdjust');
pathArray.slice(4, 5).forEach(function(path) {
pathArray.forEach(function(path) {
var shape = {};
shape.points = path;
var bound = computeBoundingBox.computePath(path);
@ -96,17 +96,7 @@ define(
pathPanel.addShape('path', shape);
});
currentRender.refresh();
// cover.removeShape(0);
// cover.removeShape(shape1);
// cover.removeShape(shape2.id);
// currentRender.removeLayer('cover');
// currentRender.removeLayer(font);
//currentRender.dispose();
}
};

View File

@ -25,6 +25,7 @@ define(
*/
function isBezierSegmentCross(p0, p1, p2, s0, s1) {
var b1 = computeBoundingBox.quadraticBezier(p0, p1, p2);
var isPointInBound = require('./util').isPointInBound;
var bound = {
x: Math.min(s0.x, s1.x),
y: Math.min(s0.y, s1.y),
@ -36,8 +37,7 @@ define(
var result = isBezierLineCross(p0, p1, p2, s0, s1);
if (result) {
return result.filter(function(p) {
return p.x >= s0.x && p.x <= s1.x
|| p.x >= s1.x && p.x <= s0.x;
return isPointInBound(bound, p, true);
});
}
}

139
src/graphics/isPathCross.js Normal file
View 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;
}
);

View File

@ -10,6 +10,7 @@
define(
function(require) {
var lang = require('common/lang');
var selectShape = require('./util/selectShape');
/**
* 初始化
@ -31,10 +32,15 @@ define(
});
render.capture.on('down', function(e) {
var shape = render.painter.getShapeIn(e);
var result = render.painter.getShapeIn(e);
if(shape) {
render.selectedShape = shape;
if(result) {
if (result.length > 1) {
render.selectedShape = selectShape(result);
}
else {
render.selectedShape = result[0];
}
}
render.camera.mx = e.x;
render.camera.my = e.y;

View File

@ -204,11 +204,13 @@ define(
getShapeIn: function(p) {
var support = this.painter.support;
var shapes = this.shapes;
var result = [];
for(var i = 0, l = shapes.length; i < l; i++) {
if (support[shapes[i].type].isIn(shapes[i], p.x, p.y)) {
return shapes[i];
result.push(shapes[i]);
}
}
return result.length ? result : false;
},
/**

View 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;
}
);