add rotate mode

This commit is contained in:
mkwiser
2014-09-14 02:34:28 +08:00
parent 5be9c8a6c3
commit e82d4f8134
27 changed files with 649 additions and 200 deletions

View File

@@ -64,16 +64,26 @@ define(
height: 42
});
var shape3 = cover.addShape('polygon', {
points: [
{x:300, y: 344},
{x:350, y: 344},
{x:450, y: 400},
{x:400, y: 400}
],
dashed: true
});
var font = currentRender.addLayer('font', {
level: 10
});
var contourAdjust = require('ttf/util/contourAdjust');
var pathAdjust = require('graphics/pathAdjust');
shape_baidu.contours.forEach(function(contour) {
var shape = {};
shape.points = contour;
shape.points = contourAdjust(contour, 1, 1, 100, 400);
shape.points = pathAdjust(contour, 1, 1, 100, 400);
font.addShape('path', shape);
});

View File

@@ -11,7 +11,7 @@ define(
function(require) {
var lang = require('common/lang');
var computeBoundingBox = require('graphics/computeBoundingBox');
var pathAdjust = require('render/util/pathAdjust');
var pathAdjust = require('graphics/pathAdjust');
var editorMode = require('./mode/editorMode');
var ContextMenu = require('./menu/ContextMenu');
@@ -56,8 +56,8 @@ define(
return;
}
render.camera.startx = e.x;
render.camera.starty = e.y;
render.camera.startX = e.x;
render.camera.startY = e.y;
setCamera(e);
me.mode.down && me.mode.down.call(me, e);
@@ -106,6 +106,17 @@ define(
me.mode.up && me.mode.up.call(me, e);
});
render.capture.on('click', function(e) {
if (me.contextMenu.visible()) {
return;
}
setCamera(e);
me.mode.click && me.mode.click.call(me, e);
});
render.capture.on('dblclick', function(e) {
if (me.contextMenu.visible()) {

View File

@@ -9,13 +9,11 @@
define(
function(require) {
var pathAdjust = require('render/util/pathAdjust');
var boundAdjust = require('render/util/boundAdjust');
var pathAdjust = require('graphics/pathAdjust');
var lang = require('common/lang');
var computeBoundingBox = require('../../graphics/computeBoundingBox');
var getTransformMatrix = require('../util/getTransformMatrix');
var computeBoundingBox = require('graphics/computeBoundingBox');
var scaleTransform = require('./scaleTransform');
var rotateTransform = require('./rotateTransform');
var updateControls = require('./updateControls');
@@ -58,57 +56,12 @@ define(
* 根据控制点做图形变换
*/
ShapesGroup.prototype.transform = function(point, camera) {
var matrix = getTransformMatrix(point.pos, this.bound, camera);
// 等比缩放
if (camera.event.shiftKey && [1, 2, 3, 4].indexOf(point.pos) >= 0) {
var scale = Math.max(Math.abs(matrix[2]), Math.abs(matrix[3]));
matrix[2] = matrix[2] >= 0 ? scale : -scale;
matrix[3] = matrix[3] >= 0 ? scale : -scale;
if (this.mode === 'scale') {
scaleTransform.call(this, point, camera);
}
// 更新shape
var shapes = this.shapes;
this.originShapes.forEach(function(originShape, index) {
var shape = lang.clone(originShape);
pathAdjust(shape.points, matrix[2], matrix[3], -matrix[0], -matrix[1]);
pathAdjust(shape.points, 1, 1, matrix[0], matrix[1]);
if (matrix[2] < 0 && !matrix[3] < 0) {
shape.points = shape.points.reverse();
}
if (matrix[3] < 0 && !matrix[2] < 0) {
shape.points = shape.points.reverse();
}
lang.extend(shapes[index], shape);
});
this.render.getLayer('font').refresh();
// 更新边界
var coverLayer = this.render.getLayer('cover');
var boundShape = coverLayer.getShape('bound');
if(!boundShape) {
boundShape = {
type: 'rect',
dashed: true,
id: 'bound'
};
coverLayer.addShape(boundShape);
else {
rotateTransform.call(this, point, camera);
}
var bound = boundAdjust(lang.clone(this.bound), matrix[2], matrix[3], -matrix[0], -matrix[1]);
boundAdjust(bound, 1, 1, matrix[0], matrix[1]);
lang.extend(boundShape, bound);
coverLayer.refresh();
};
/**

View File

@@ -0,0 +1,84 @@
/**
* @file getRotateMatrix.js
* @author mengke01
* @date
* @description
* 获得变换的矩阵
*/
define(
function(require) {
var getAngle = require('math/getAngle');
/**
* 获得变换矩阵
*
* @param {number} pos 变换位置
* @param {Object} bound 边界
* @param {Object} camera 镜头对象
* @return {Array} 变换矩阵x,y,xScale,yScale
*/
function getRotateMatrix(pos, bound, camera) {
// x, y, xscale 相对符号, yscale 相对符号
var matrix = [
bound.x + bound.width / 2,
bound.y + bound.height / 2,
0
];
switch (pos) {
case 1:
case 2:
case 3:
case 4:
matrix[2] = getAngle(
camera.startX - matrix[0], camera.startY - matrix[1],
camera.x - matrix[0], camera.y - matrix[1]
);
return matrix;
case 5:
matrix[0] = 0;
matrix[1] = bound.y + bound.height;
matrix[2] = getAngle(
0, bound.height,
camera.x - camera.startX, bound.height
);
return matrix;
case 7:
matrix[0] = 0;
matrix[1] = bound.y;
matrix[2] = getAngle(
0, -bound.height,
camera.x - camera.startX, -bound.height
);
return matrix;
case 6:
matrix[0] = bound.x;
matrix[1] = 0;
matrix[2] = getAngle(
bound.width, 0,
bound.width, camera.y - camera.startY
);
return matrix;
case 8:
matrix[0] = bound.x + bound.width;
matrix[1] = 0;
matrix[2] = getAngle(
-bound.width, 0,
-bound.width, camera.y - camera.startY
);
return matrix;
};
return matrix;
}
return getRotateMatrix;
}
);

View File

@@ -1,5 +1,5 @@
/**
* @file getTransformMatrix.js
* @file getScaleMatrix.js
* @author mengke01
* @date
* @description
@@ -19,7 +19,7 @@ define(
* @param {Object} camera 镜头对象
* @return {Array} 变换矩阵x,y,xScale,yScale
*/
function getTransformMatrix(pos, bound, camera) {
function getScaleMatrix(pos, bound, camera) {
// x, y, xscale 相对符号, yscale 相对符号
var matrix = [
@@ -83,6 +83,6 @@ define(
}
return getTransformMatrix;
return getScaleMatrix;
}
);

View File

@@ -0,0 +1,87 @@
/**
* @file rotateTransform.js
* @author mengke01
* @date
* @description
* 旋转变换
*/
define(
function(require) {
var getRotateMatrix = require('./getRotateMatrix');
var pathRotate = require('graphics/pathRotate');
var pathLean = require('graphics/pathLean');
var lang = require('common/lang');
/**
* 旋转变换
*
* @param {Object} point 参考点
* @param {Object} camera 镜头对象
*/
function rotateTransform(point, camera) {
var matrix = getRotateMatrix(point.pos, this.bound, camera);
var transformer = point.pos <= 4 ? pathRotate : pathLean;
// 更新shape
var shapes = this.shapes;
this.originShapes.forEach(function(originShape, index) {
var shape = lang.clone(originShape);
transformer(shape.points, matrix[2], matrix[0], matrix[1]);
lang.extend(shapes[index], shape);
});
this.render.getLayer('font').refresh();
// 更新边界
var coverLayer = this.render.getLayer('cover');
var boundShape = coverLayer.getShape('bound');
if(!boundShape) {
boundShape = {
type: 'polygon',
dashed: true,
id: 'bound'
};
coverLayer.addShape(boundShape);
}
var bound = this.bound;
boundShape.points = transformer(
[
{x: bound.x,y:bound.y},
{x: bound.x + bound.width, y:bound.y},
{x: bound.x + bound.width, y:bound.y + bound.height},
{x: bound.x, y:bound.y + bound.height},
],
matrix[2], matrix[0], matrix[1]
);
// 更新中心点
var boundCenter = coverLayer.getShape('boundcenter');
if(!boundCenter) {
boundCenter = {
type: 'cpoint',
id: 'boundcenter',
x: bound.x + bound.width / 2,
y: bound.y + bound.height / 2
};
coverLayer.addShape(boundCenter);
}
boundCenter.x = (boundShape.points[0].x + boundShape.points[2].x) / 2;
boundCenter.y = (boundShape.points[0].y + boundShape.points[2].y) / 2;
coverLayer.refresh();
}
return rotateTransform;
}
);

View File

@@ -0,0 +1,88 @@
/**
* @file scaleTransform.js
* @author mengke01
* @date
* @description
* 缩放变换
*/
define(
function(require) {
var getScaleMatrix = require('./getScaleMatrix');
var pathAdjust = require('graphics/pathAdjust');
var lang = require('common/lang');
/**
* 缩放变换
*
* @param {Object} point 参考点
* @param {Object} camera 镜头对象
*/
function scaleTransform(point, camera) {
var matrix = getScaleMatrix(point.pos, this.bound, camera);
// 等比缩放
if (camera.event.shiftKey && [1, 2, 3, 4].indexOf(point.pos) >= 0) {
var scale = Math.max(Math.abs(matrix[2]), Math.abs(matrix[3]));
matrix[2] = matrix[2] >= 0 ? scale : -scale;
matrix[3] = matrix[3] >= 0 ? scale : -scale;
}
// 更新shape
var shapes = this.shapes;
this.originShapes.forEach(function(originShape, index) {
var shape = lang.clone(originShape);
pathAdjust(shape.points, matrix[2], matrix[3], -matrix[0], -matrix[1]);
pathAdjust(shape.points, 1, 1, matrix[0], matrix[1]);
if (matrix[2] < 0 && !matrix[3] < 0) {
shape.points = shape.points.reverse();
}
if (matrix[3] < 0 && !matrix[2] < 0) {
shape.points = shape.points.reverse();
}
lang.extend(shapes[index], shape);
});
this.render.getLayer('font').refresh();
// 更新边界
var coverLayer = this.render.getLayer('cover');
var boundShape = coverLayer.getShape('bound');
if(!boundShape) {
boundShape = {
type: 'polygon',
dashed: true,
id: 'bound'
};
coverLayer.addShape(boundShape);
}
var bound = this.bound;
var points = pathAdjust(
[
{x: bound.x,y:bound.y},
{x: bound.x + bound.width, y:bound.y},
{x: bound.x + bound.width, y:bound.y + bound.height},
{x: bound.x, y:bound.y + bound.height},
],
matrix[2], matrix[3], -matrix[0], -matrix[1]
);
pathAdjust(points, 1, 1, matrix[0], matrix[1]);
boundShape.points = points;
coverLayer.refresh();
}
return scaleTransform;
}
);

View File

@@ -18,25 +18,26 @@ define(
function updateControls(bound) {
if (!this.controls) {
this.controls = [{
type: 'rect',
dashed: true,
selectable: false
}];
for (var i = 0; i < 8; i++) {
this.controls.push({
type: 'point'
});
}
// 虚线框
this.controls = [
{
type: 'polygon',
dashed: true,
selectable: false
},
{}, {}, {}, {}, {}, {}, {}, {}
];
}
var points = [
// 虚线框
{
x: bound.x,
y: bound.y,
width: bound.width,
height: bound.height
points: [
{x: bound.x,y:bound.y},
{x: bound.x + bound.width, y:bound.y},
{x: bound.x + bound.width, y:bound.y + bound.height},
{x: bound.x, y:bound.y + bound.height},
]
},
// 控制点
@@ -55,9 +56,13 @@ define(
{x: bound.x, y: bound.y + bound.height / 2, pos: 8},
];
var mode = this.mode;
var controls = this.controls;
points.forEach(function(p, index) {
lang.extend(controls[index], p);
points.forEach(function(p, i) {
lang.extend(controls[i], p);
if (i > 0) {
controls[i].type = mode == 'rotate' && i <= 4 ? 'cpoint' : 'point';
}
});
var coverLayer = this.render.getLayer('cover');

View File

@@ -11,14 +11,26 @@ define(
function(require) {
// 不同位置的光标集合
return {
1: 'nw-resize',
2: 'ne-resize',
3: 'se-resize',
4: 'sw-resize',
5: 's-resize',
6: 'e-resize',
7: 'n-resize',
8: 'w-resize'
};;
scale: {
1: 'nw-resize',
2: 'ne-resize',
3: 'se-resize',
4: 'sw-resize',
5: 's-resize',
6: 'e-resize',
7: 'n-resize',
8: 'w-resize'
},
rotate: {
1: 'pointer',
2: 'pointer',
3: 'pointer',
4: 'pointer',
5: 'e-resize',
6: 's-resize',
7: 'w-resize',
8: 'n-resize'
}
};
}
);

View File

@@ -11,7 +11,7 @@ define(
function(require) {
var computeBoundingBox = require('graphics/computeBoundingBox');
var pathAdjust = require('render/util/pathAdjust');
var pathAdjust = require('graphics/pathAdjust');
var lang = require('common/lang');

View File

@@ -48,6 +48,7 @@ define(
}
else {
this.currentGroup.setShapes([shape]);
this.currentGroup.setMode('scale');
this.currentGroup.refresh();
return;
}
@@ -96,6 +97,20 @@ define(
}
},
/**
* 点击
*/
click: function(e) {
// 变换编辑模式
if (e.time > 400 && this.currentGroup && !this.currentPoint) {
this.currentGroup.setMode(this.currentGroup.mode == 'scale' ? 'rotate' : 'scale');
this.currentGroup.refresh();
}
else {
this.currentPoint = null;
}
},
/**
* 开始模式
*/
@@ -105,12 +120,12 @@ define(
this.currentGroup = new ShapesGroup(shapes, this.render);
this.currentGroup.refresh();
// 注册鼠标样式
me.render.capture.on('move', me.__moveEvent = function (e) {
var shapes = coverLayer.getShapeIn(e);
if(shapes) {
me.render.setCursor(POS_CUSOR[shapes[0].pos] || 'default');
me.render.setCursor(POS_CUSOR[me.currentGroup.mode][shapes[0].pos] || 'default');
}
else {
me.render.setCursor('default');

View File

@@ -5,81 +5,39 @@
* @description
* 判断点是否在polygon内部
*
* copy from zrender:
* https://github.com/ecomfe/zrender
*/
define(
function(require) {
var isSegmentRayCross = require('./isSegmentRayCross');
/**
* 多边形包含判断
* 警告:下面这段代码会很难看,建议跳过~
* 多边形包含判断, 射线法
*/
function isInsidePolygon(pointList, x, y) {
/**
* 射线判别法
* 如果一个点在多边形内部,任意角度做射线肯定会与多边形要么有一个交点,要么有与多边形边界线重叠
* 如果一个点在多边形外部,任意角度做射线要么与多边形有一个交点,
* 要么有两个交点,要么没有交点,要么有与多边形边界线重叠。
*/
var i;
var j;
var polygon = pointList;
var N = polygon.length;
var inside = false;
var redo = true;
var v;
function isInsidePolygon(points, p) {
for (i = 0; i < N; ++i) {
// 是否在顶点上
if (polygon[i].x == x && polygon[i].y == y ) {
redo = false;
inside = true;
break;
}
}
var zCount = 0, p0, p1, result;
for (var i = 0, l = points.length; i < l ; i++) {
p0 = points[i];
p1 = points[i === l - 1 ? 0 : i + 1];
if (redo) {
redo = false;
inside = false;
for (i = 0,j = N - 1; i < N; j = i++) {
if ((polygon[i].y < y && y < polygon[j].y)
|| (polygon[j].y < y && y < polygon[i].y)
) {
if (x <= polygon[i].x || x <= polygon[j].x) {
v = (y - polygon[i].y)
* (polygon[j].x - polygon[i].x)
/ (polygon[j].y - polygon[i].y)
+ polygon[i].x;
if (x < v) { // 在线的左侧
inside = !inside;
}
else if (x == v) { // 在线上
inside = true;
break;
}
}
if (result = isSegmentRayCross(p0, p1, p)) {
// 在线段上
if (result.y == p.y) {
return true;
}
else if (y == polygon[i].y) {
if (x < polygon[i].x) { // 交点在顶点上
polygon[i].y > polygon[j].y ? --y : ++y;
//redo = true;
break;
}
if (p1.y > p0.y) {
zCount++;
}
else if (polygon[i].y == polygon[j].y // 在水平的边界线上
&& y == polygon[i].y
&& ((polygon[i].x < x && x < polygon[j].x)
|| (polygon[j].x < x && x < polygon[i].x))
) {
inside = true;
break;
else {
zCount--;
}
}
}
return inside;
return !!zCount;
}
return isInsidePolygon;

View File

@@ -1,5 +1,5 @@
/**
* @file contourAdjust.js
* @file pathAdjust.js
* @author mengke01
* @date
* @description
@@ -20,7 +20,7 @@ define(
* @param {number} offsetY y偏移
* @return {number} contour 坐标点
*/
function contourAdjust(contour, scaleX, scaleY, offsetX, offsetY) {
function pathAdjust(contour, scaleX, scaleY, offsetX, offsetY) {
var scaleX = scaleX == undefined ? 1 : scaleX;
var scaleY = scaleY == undefined ? 1 : scaleY;
var x = offsetX || 0;
@@ -34,6 +34,6 @@ define(
return contour;
}
return contourAdjust;
return pathAdjust;
}
);

View File

@@ -14,6 +14,8 @@ define(
* 遍历路径的路径集合
*
* @param {Array} contour 坐标点集
* @param {Function} callBack 回调函数参数集合command, p0, p1, p2
* 其中command = L 或者 Q表示直线或者贝塞尔曲线
*/
function pathIterator(contour, callBack) {

47
src/graphics/pathLean.js Normal file
View File

@@ -0,0 +1,47 @@
/**
* @file pathLean.js
* @author mengke01
* @date
* @description
* path倾斜变换
*/
define(
function(require) {
/**
* path倾斜变换
*
* @param {Object} contour 坐标点
* @param {number} angle 角度
* @param {number} offsetX x偏移
* @param {number} offsetY y偏移
* @return {number} contour 坐标点
*/
function pathLean(contour, angle, offsetX, offsetY) {
var angle = angle == undefined ? 0 : angle;
var x = offsetX || 0;
var y = offsetY || 0;
var tan = Math.tan(angle);
var px, py;
// x 平移
if (x == 0) {
contour.forEach(function(p) {
p.x += tan * (p.y - offsetY);
});
}
// y平移
else {
contour.forEach(function(p) {
p.y += tan * (p.x - offsetX);
});
}
return contour;
}
return pathLean;
}
);

View File

@@ -0,0 +1,44 @@
/**
* @file pathRotate.js
* @author mengke01
* @date
* @description
* 路径旋转
*/
define(
function(require) {
/**
* 对path坐标进行调整
*
* @param {Object} contour 坐标点
* @param {number} angle 角度
* @param {number} centerX x偏移
* @param {number} centerY y偏移
* @return {number} contour 坐标点
*/
function pathRotate(contour, angle, centerX, centerY) {
var angle = angle == undefined ? 0 : angle;
var x = centerX || 0;
var y = centerY || 0;
var cos = Math.cos(angle);
var sin = Math.sin(angle);
var px, py;
//x1=cos(angle)*x-sin(angle)*y;
//y1=cos(angle)*y+sin(angle)*x;
contour.forEach(function(p) {
px = cos * (p.x - x) - sin * (p.y - y);
py = cos * (p.y - y) + sin * (p.x - x);
p.x = px + x;
p.y = py + y;
});
return contour;
}
return pathRotate;
}
);

37
src/math/getAngle.js Normal file
View File

@@ -0,0 +1,37 @@
/**
* @file getAngle.js
* @author mengke01
* @date
* @description
* 获取向量夹角,带方向
*/
define(
function(require) {
/**
* 获取向量夹角, 相对于坐标原点
*
* @param {number} x1 起始x
* @param {number} y1 起始y
* @param {number} x2 结束x
* @param {number} y2 结束y
* @return {number} 弧度
*/
function getAngle(x1, y1, x2, y2) {
// cos(θ) = (x1x2+y1y2)/[√(x1²+y1²)*√(x2²+y2²)]
var angle = Math.acos( (x1 * x2 + y1 * y2) / Math.sqrt(x1*x1 + y1*y1) / Math.sqrt(x2*x2 + y2*y2));
// 有向线段内积,判断左右
//(xb - xa) * (yc - ya) - (xc - xa) * (yb - ya);
if (x1 * y2 - x2 * y1 < 0) {
angle = 2 * Math.PI - angle;
}
return angle;
}
return getAngle;
}
);

View File

@@ -32,9 +32,13 @@ define(
});
render.capture.on('down', function(e) {
var result = render.getShapeIn(e);
var result = render.getLayer('cover').getShapeIn(e);
if(result) {
render.selectedShape = result[0];
}
else {
result = render.getLayer('font').getShapeIn(e);
if (result.length > 1) {
render.selectedShape = selectShape(result);
}
@@ -42,6 +46,8 @@ define(
render.selectedShape = result[0];
}
}
render.camera.x = e.x;
render.camera.y = e.y;
});

View File

@@ -35,7 +35,6 @@ define(
function setContextStyle(context, options) {
context.fillStyle = options.fillColor || 'black';
context.strokeStyle = options.strokeColor || 'black';
context.strokeWidth = options.strokeWidth || 1;
context.lineWidth = options.lineWidth || 1;
context.font = options.font || "normal 10px arial";
}

View File

@@ -93,7 +93,6 @@ define(
mousemove: lang.bind(mousemove, this),
mousedown: lang.bind(mousedown, this),
dblclick: lang.bind(dblclick, this),
click: lang.bind(click, this),
mouseover: lang.bind(mouseover, this),
mouseout: lang.bind(mouseout, this),
mouseup: lang.bind(mouseup, this)
@@ -104,7 +103,6 @@ define(
target.addEventListener('mousemove', this.handlers.mousemove, false);
target.addEventListener('mousedown', this.handlers.mousedown, false);
target.addEventListener('dblclick', this.handlers.dblclick, false);
target.addEventListener('click', this.handlers.click, false);
target.addEventListener('mouseover', this.handlers.mouseover, false);
target.addEventListener('mouseout', this.handlers.mouseout, false);
document.addEventListener('mouseup', this.handlers.mouseup, false);
@@ -127,6 +125,7 @@ define(
this.startX = event.x;
this.startY = event.y;
this.startTime = Date.now();
this.isDown = true;
// 左键
@@ -138,22 +137,6 @@ define(
}
}
/**
* 点击事件
*
* @param {Object} e 事件参数
*/
function click(e) {
prevent(e);
if(false === this.events.click) {
return;
}
this.fire('click', getEvent(e));
}
/**
* 双击事件
*
@@ -221,6 +204,7 @@ define(
}
var event = getEvent(e);
event.time = Date.now() - this.startTime;
// 左键
@@ -236,6 +220,10 @@ define(
this.isDragging = false;
this.fire('dragend', event);
}
else if(this.isDown && !this.isDragging && false !== this.events.click) {
this.isDragging = false;
this.fire('click', event);
}
this.isDown = false;
}

View File

@@ -11,7 +11,7 @@ define(
function(require) {
var ShapeConstructor = require('./Shape');
var isInsidePath = require('../../graphics/isInsidePath');
var pathAdjust = require('../util/pathAdjust');
var pathAdjust = require('graphics/pathAdjust');
var drawContour = require('ttf/util/drawContour');
var computeBoundingBox = require('graphics/computeBoundingBox');
var proto = {

View File

@@ -1,8 +1,124 @@
/**
* @file Polygon.js
* @file Rect.js
* @author mengke01
* @date
* @description
* 多边形绘制
* 绘制多边形
*/
define(
function(require) {
var dashedLineTo = require('../util/dashedLineTo');
var pathAdjust = require('graphics/pathAdjust');
var computeBoundingBox = require('graphics/computeBoundingBox');
var isInsidePolygon = require('graphics/isInsidePolygon');
var proto = {
type: 'polygon',
/**
* 对形状进行缩放平移调整
*
* @param {Object} shape shape对象
* @param {Object} camera camera对象
* @return {Object} shape对象
*/
adjust: function(shape, camera) {
pathAdjust(shape.points, camera.ratio, camera.ratio, -camera.center.x, -camera.center.y);
pathAdjust(shape.points, 1, 1, camera.center.x, camera.center.y);
},
/**
* 移动指定位置
*
* @return {Object} shape对象
*/
move: function(shape, mx, my) {
pathAdjust(shape.points, 1, 1, mx, my);
return shape;
},
/**
* 获取shape的矩形区域
*
* @param {Object} shape shape数据
* @param {Object} 矩形区域
*/
getRect: function(shape) {
return computeBoundingBox.computeBounding(shape.points);
},
/**
* 判断点是否在shape内部
*
* @param {Object} shape shape数据
* @param {number} x x偏移
* @param {number} y y偏移
* @param {boolean} 是否
*/
isIn: function(shape, x, y) {
var bound = computeBoundingBox.computeBounding(shape.points);
if(
x <= bound.x + bound.width
&& x >= bound.x
&& y <= bound.y + bound.height
&& y >= bound.y
) {
return isInsidePolygon(shape.points, {
x: x,
y: y
});
}
return false;
},
/**
* 绘制一个shape对象
*
* @param {CanvasContext} ctx canvas的context
* @param {Object} shape shape数据
*/
draw: function(ctx, shape) {
ctx.translate(0.5, 0.5);
var points = shape.points;
var i = 0, l = points.length;
if(shape.dashed) {
for (; i < l - 1; i++) {
dashedLineTo(ctx,
Math.round(points[i].x), Math.round(points[i].y),
Math.round(points[i+1].x), Math.round(points[i+1].y)
);
};
dashedLineTo(ctx,
Math.round(points[l-1].x), Math.round(points[l-1].y),
Math.round(points[0].x), Math.round(points[0].y)
);
}
else {
ctx.moveTo(Math.round(points[0].x), Math.round(points[0].y));
for (i = 1; i < l; i++) {
ctx.lineTo(
Math.round(points[i].x), Math.round(points[i].y)
);
};
ctx.lineTo(
Math.round(points[0].x), Math.round(points[0].y)
);
}
ctx.translate(-0.5, -0.5);
}
};
return require('./Shape').derive(proto);
}
);

View File

@@ -1,5 +1,5 @@
/**
* @file DashedRect.js
* @file Rect.js
* @author mengke01
* @date
* @description
@@ -62,13 +62,13 @@ define(
dashedLineTo(ctx, x + w, y, x + w, y + h);
dashedLineTo(ctx, x + w, y + h, x, y + h);
dashedLineTo(ctx, x, y + h, x, y);
}
else {
ctx.lineTo(x, y, x + w, y);
ctx.lineTo(x + w, y, x + w, y + h);
ctx.lineTo(x + w, y + h, x, y + h);
ctx.lineTo(x, y + h, x, y);
ctx.moveTo(x, y);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w, y + h);
ctx.lineTo(x, y + h);
ctx.lineTo(x, y);
}
ctx.translate(-0.5, -0.5);
}

View File

@@ -12,8 +12,9 @@ define(
var support = {
circle: require('./Circle'),
cpoint: require('./CirclePoint'),
rect: require('./Rect'),
point: require('./Point'),
rect: require('./Rect'),
polygon: require('./Polygon'),
font: require('./Font'),
path: require('./Path'),
axis: require('./Axis')

View File

@@ -1,14 +0,0 @@
/**
* @file pathAdjust.js
* @author mengke01
* @date
* @description
* 路径调整
*/
define(
function(require) {
return require('ttf/util/contourAdjust');
}
);

View File

@@ -13,7 +13,7 @@ define(
var lang = require('common/lang');
var computeBoundingBox = require('../../graphics/computeBoundingBox');
var isPathCross = require('../../graphics/isPathCross');
var pathAdjust = require('./pathAdjust');
var pathAdjust = require('graphics/pathAdjust');
/**
* 从待选的shape中选择一个作为选中的shape