You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

361 rivejä
8.8 KiB

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