/** * 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; } );