/**
|
|
* PS钢笔工具所用的表示可绘制的控制点集合对象
|
|
*/
|
|
|
|
define( function ( require, exports, module ) {
|
|
|
|
var Utils = require( "core/utils" ),
|
|
Rect = require( "graphic/rect" ),
|
|
Color = require( "graphic/color" ),
|
|
Pen = require( "graphic/pen" ),
|
|
Line = require( "graphic/line" ),
|
|
Circle = require( "graphic/circle" );
|
|
|
|
var GroupUtils = {
|
|
|
|
listenVertex: function ( point, group, index ) {
|
|
|
|
GroupUtils.listen( PointGroup.TYPE_VERTEX, point, group, index );
|
|
|
|
},
|
|
|
|
listenForward: function ( point, group, index ) {
|
|
|
|
GroupUtils.listen( PointGroup.TYPE_FORWARD, point, group, index );
|
|
|
|
},
|
|
|
|
listenBackward: function ( point, group, index ) {
|
|
|
|
GroupUtils.listen( PointGroup.TYPE_BACKWARD, point, group, index );
|
|
|
|
},
|
|
|
|
listen: function ( pointType, point, group, index ) {
|
|
|
|
point.on( "mousedown", function ( e ) {
|
|
|
|
group.trigger( 'pointmousedown', {
|
|
targetPointType: pointType,
|
|
targetPointIndex: index
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var PointGroup = require( "core/class" ).createClass( "PointGroup", {
|
|
|
|
base: require( "graphic/group" ),
|
|
|
|
constructor: function () {
|
|
|
|
this.callBase();
|
|
|
|
this.points = [];
|
|
this.pointShapes = [];
|
|
|
|
this.exterior = {
|
|
|
|
vertex: {
|
|
width: 4 * 100,
|
|
height: 4 * 100
|
|
},
|
|
|
|
control: {
|
|
|
|
radius: 1.5 * 100
|
|
|
|
},
|
|
|
|
pen: {
|
|
width: 1 * 100
|
|
}
|
|
|
|
};
|
|
|
|
this.handler = {
|
|
'mousedown': [],
|
|
'mouseup': []
|
|
};
|
|
|
|
},
|
|
|
|
indexOf: function ( bezierPoint ) {
|
|
|
|
var index = -1;
|
|
|
|
if ( this.points.indexOf ) {
|
|
return this.points.indexOf( bezierPoint );
|
|
} else {
|
|
|
|
Utils.each( this.points, function ( point, i ) {
|
|
|
|
if ( point === bezierPoint ) {
|
|
index = i;
|
|
return false;
|
|
}
|
|
|
|
} );
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// 获取顶点宽度
|
|
getVertexWidth: function () {
|
|
return this.exterior.vertex.width;
|
|
},
|
|
|
|
getPoints: function () {
|
|
|
|
return this.points.slice( 0 );
|
|
|
|
},
|
|
|
|
getPointByIndex: function ( index ) {
|
|
|
|
return this.points[ index ] || null;
|
|
|
|
},
|
|
|
|
getLastPoint: function () {
|
|
|
|
return this.points[ this.points.length - 1 ] || null;
|
|
|
|
},
|
|
|
|
addPoint: function ( point ) {
|
|
|
|
point.container = this;
|
|
|
|
this.points.push( point );
|
|
|
|
this.onChanged();
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
onChanged: function () {
|
|
|
|
this._draw();
|
|
|
|
},
|
|
|
|
update: function ( sourcePoint ) {
|
|
|
|
// 数据发生改变, 重绘当前点
|
|
this._redraw( sourcePoint );
|
|
|
|
},
|
|
|
|
// 选中给定索引的点,该操作会引起其他点的连锁反应
|
|
selectPoint: function ( index ) {
|
|
|
|
var shapeGroup = this.pointShapes[ index ];
|
|
|
|
// 重绘当前点
|
|
this._redraw( this.getPointByIndex( index ) );
|
|
|
|
// 清空其他点的
|
|
Utils.each( this.pointShapes, function ( shape, i ) {
|
|
|
|
if ( i !== index ) {
|
|
|
|
this._clearShapePoint( i );
|
|
|
|
}
|
|
|
|
}, this );
|
|
|
|
// 更新辅助点
|
|
if ( index > 0 ) {
|
|
this._drawAssistPoint( index-1 );
|
|
}
|
|
|
|
},
|
|
|
|
_draw: function () {
|
|
|
|
var point = this.getLastPoint(),
|
|
currentIndex = this.pointShapes.length;
|
|
|
|
this._drawPoint( point, currentIndex );
|
|
|
|
// 绘制辅助点
|
|
if ( currentIndex > 0 ) {
|
|
this._drawAssistPoint( currentIndex - 1 );
|
|
}
|
|
|
|
},
|
|
|
|
_redraw: function ( point ) {
|
|
|
|
//寻找源所对应的图形
|
|
var index = this.indexOf( point ),
|
|
shape = this.pointShapes[ index ];
|
|
|
|
var vertex = point.getVertex(),
|
|
forward = point.getForward(),
|
|
backward = point.getBackward();
|
|
|
|
// 更新图形
|
|
shape.forward.setCenter( forward.x, forward.y );
|
|
shape.backward.setCenter( backward.x, backward.y );
|
|
shape.line.setPoint1( forward.x, forward.y ).setPoint2( backward.x, backward.y );
|
|
shape.vertex.setPosition( vertex.x - this.exterior.vertex.width / 2, vertex.y - this.exterior.vertex.height / 2 );
|
|
|
|
this._stroke( shape.vertex );
|
|
|
|
},
|
|
|
|
_drawPoint: function ( point, index ) {
|
|
|
|
var forward = point.getForward(),
|
|
backward = point.getBackward(),
|
|
shape = null;
|
|
|
|
shape = {};
|
|
this.pointShapes[ index ] = shape;
|
|
|
|
//控制线
|
|
shape.line = this._drawLine( forward, backward );
|
|
//前置控制点
|
|
shape.forward = this._drawForward( forward, index );
|
|
//后置控制点
|
|
shape.backward = this._drawBackward( backward, index );
|
|
|
|
//vertex
|
|
shape.vertex = this._drawVertex( point.getVertex(), index );
|
|
|
|
},
|
|
|
|
// 清理指定索引的图形点, 使得该点仅显示一个顶点
|
|
_clearShapePoint: function ( index ) {
|
|
|
|
var shape = this.pointShapes[ index ],
|
|
// 当前的包含的数据点
|
|
vertex = this.points[ index ].getVertex();
|
|
|
|
shape.line.setPoint1( vertex.x, vertex.y ).setPoint2( vertex.x, vertex.y );
|
|
shape.forward.setCenter( vertex.x, vertex.y );
|
|
shape.backward.setCenter( vertex.x, vertex.y );
|
|
|
|
this._stroke( shape.vertex, "white" );
|
|
|
|
},
|
|
|
|
// 根据指定的索引, 把该索引所对应的点更新成辅助点
|
|
// 一个辅助点是当前曲线区间的起点, 它显示出该辅助点的forward控制点和连线
|
|
_drawAssistPoint: function ( index ) {
|
|
|
|
var shape = this.pointShapes[ index ],
|
|
// 当前的包含的数据点
|
|
bezierPoint = this.points[ index ],
|
|
forward = bezierPoint.getForward(),
|
|
vertex = bezierPoint.getVertex();
|
|
|
|
shape.line.setPoint1( vertex.x, vertex.y ).setPoint2( forward.x, forward.y );
|
|
shape.forward.setCenter( forward.x, forward.y );
|
|
shape.backward.setCenter( vertex.x, vertex.y );
|
|
|
|
this._stroke( shape.vertex, "white" );
|
|
|
|
// 清理前一次的辅助点
|
|
if ( index > 1 ) {
|
|
|
|
this._clearShapePoint( index - 1 );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_drawVertex: function ( vertex, index ) {
|
|
|
|
var width = this.exterior.vertex.width,
|
|
height = this.exterior.vertex.height,
|
|
vertextRect = new Rect( width, height, vertex.x - width / 2 , vertex.y - height / 2 );
|
|
|
|
//记录下图形
|
|
this._stroke( vertextRect );
|
|
|
|
this.addShape( vertextRect );
|
|
|
|
GroupUtils.listenVertex( vertextRect, this, index );
|
|
|
|
return vertextRect;
|
|
|
|
},
|
|
|
|
_drawForward: function ( point, index ) {
|
|
|
|
var forwardPoint = this._drawControl( point );
|
|
|
|
GroupUtils.listenForward( forwardPoint, this, index );
|
|
|
|
return forwardPoint;
|
|
|
|
},
|
|
|
|
_drawBackward: function ( point, index ) {
|
|
|
|
var backwardPoint = this._drawControl( point );
|
|
|
|
GroupUtils.listenBackward( backwardPoint, this, index );
|
|
|
|
return backwardPoint;
|
|
|
|
},
|
|
|
|
_drawControl: function ( point ) {
|
|
|
|
var styles = this.exterior.control,
|
|
radius = styles.radius,
|
|
controlPoint = new Circle( radius, point.x, point.y );
|
|
|
|
this._stroke( controlPoint );
|
|
|
|
this.addShape( controlPoint );
|
|
|
|
return controlPoint;
|
|
|
|
},
|
|
|
|
_drawLine: function ( forward, backward ) {
|
|
|
|
var line = new Line ( forward.x, forward.y, backward.x, backward.y );
|
|
|
|
line.stroke( new Pen( new Color( "#2d2d2d" ) ).setWidth( this.exterior.pen.width ) );
|
|
|
|
this.addShape( line );
|
|
|
|
return line;
|
|
|
|
},
|
|
|
|
_stroke: function ( shape, fillColor ) {
|
|
|
|
shape.stroke( new Pen( new Color( "#2d2d2d" ) ).setWidth( this.exterior.pen.width ) );
|
|
shape.fill( new Color( fillColor || "black" ) );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
Utils.extend( PointGroup, {
|
|
|
|
// 顶点类型常量
|
|
TYPE_VERTEX: "vertex",
|
|
TYPE_FORWARD: "forward",
|
|
TYPE_BACKWARD: "backward"
|
|
|
|
} );
|
|
|
|
return PointGroup;
|
|
|
|
} );
|