demo.pointgroup.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /**
  2. * PS钢笔工具所用的表示可绘制的控制点集合对象
  3. */
  4. define( function ( require, exports, module ) {
  5. var Utils = require( "core/utils" ),
  6. Rect = require( "graphic/rect" ),
  7. Color = require( "graphic/color" ),
  8. Pen = require( "graphic/pen" ),
  9. Line = require( "graphic/line" ),
  10. Circle = require( "graphic/circle" );
  11. var GroupUtils = {
  12. listenVertex: function ( point, group, index ) {
  13. GroupUtils.listen( PointGroup.TYPE_VERTEX, point, group, index );
  14. },
  15. listenForward: function ( point, group, index ) {
  16. GroupUtils.listen( PointGroup.TYPE_FORWARD, point, group, index );
  17. },
  18. listenBackward: function ( point, group, index ) {
  19. GroupUtils.listen( PointGroup.TYPE_BACKWARD, point, group, index );
  20. },
  21. listen: function ( pointType, point, group, index ) {
  22. point.on( "mousedown", function ( e ) {
  23. group.trigger( 'pointmousedown', {
  24. targetPointType: pointType,
  25. targetPointIndex: index
  26. } );
  27. } );
  28. }
  29. };
  30. var PointGroup = require( "core/class" ).createClass( "PointGroup", {
  31. base: require( "graphic/group" ),
  32. constructor: function () {
  33. this.callBase();
  34. this.points = [];
  35. this.pointShapes = [];
  36. this.exterior = {
  37. vertex: {
  38. width: 4 * 100,
  39. height: 4 * 100
  40. },
  41. control: {
  42. radius: 1.5 * 100
  43. },
  44. pen: {
  45. width: 1 * 100
  46. }
  47. };
  48. this.handler = {
  49. 'mousedown': [],
  50. 'mouseup': []
  51. };
  52. },
  53. indexOf: function ( bezierPoint ) {
  54. var index = -1;
  55. if ( this.points.indexOf ) {
  56. return this.points.indexOf( bezierPoint );
  57. } else {
  58. Utils.each( this.points, function ( point, i ) {
  59. if ( point === bezierPoint ) {
  60. index = i;
  61. return false;
  62. }
  63. } );
  64. return index;
  65. }
  66. },
  67. // 获取顶点宽度
  68. getVertexWidth: function () {
  69. return this.exterior.vertex.width;
  70. },
  71. getPoints: function () {
  72. return this.points.slice( 0 );
  73. },
  74. getPointByIndex: function ( index ) {
  75. return this.points[ index ] || null;
  76. },
  77. getLastPoint: function () {
  78. return this.points[ this.points.length - 1 ] || null;
  79. },
  80. addPoint: function ( point ) {
  81. point.container = this;
  82. this.points.push( point );
  83. this.onChanged();
  84. return this;
  85. },
  86. onChanged: function () {
  87. this._draw();
  88. },
  89. update: function ( sourcePoint ) {
  90. // 数据发生改变, 重绘当前点
  91. this._redraw( sourcePoint );
  92. },
  93. // 选中给定索引的点,该操作会引起其他点的连锁反应
  94. selectPoint: function ( index ) {
  95. var shapeGroup = this.pointShapes[ index ];
  96. // 重绘当前点
  97. this._redraw( this.getPointByIndex( index ) );
  98. // 清空其他点的
  99. Utils.each( this.pointShapes, function ( shape, i ) {
  100. if ( i !== index ) {
  101. this._clearShapePoint( i );
  102. }
  103. }, this );
  104. // 更新辅助点
  105. if ( index > 0 ) {
  106. this._drawAssistPoint( index-1 );
  107. }
  108. },
  109. _draw: function () {
  110. var point = this.getLastPoint(),
  111. currentIndex = this.pointShapes.length;
  112. this._drawPoint( point, currentIndex );
  113. // 绘制辅助点
  114. if ( currentIndex > 0 ) {
  115. this._drawAssistPoint( currentIndex - 1 );
  116. }
  117. },
  118. _redraw: function ( point ) {
  119. //寻找源所对应的图形
  120. var index = this.indexOf( point ),
  121. shape = this.pointShapes[ index ];
  122. var vertex = point.getVertex(),
  123. forward = point.getForward(),
  124. backward = point.getBackward();
  125. // 更新图形
  126. shape.forward.setCenter( forward.x, forward.y );
  127. shape.backward.setCenter( backward.x, backward.y );
  128. shape.line.setPoint1( forward.x, forward.y ).setPoint2( backward.x, backward.y );
  129. shape.vertex.setPosition( vertex.x - this.exterior.vertex.width / 2, vertex.y - this.exterior.vertex.height / 2 );
  130. this._stroke( shape.vertex );
  131. },
  132. _drawPoint: function ( point, index ) {
  133. var forward = point.getForward(),
  134. backward = point.getBackward(),
  135. shape = null;
  136. shape = {};
  137. this.pointShapes[ index ] = shape;
  138. //控制线
  139. shape.line = this._drawLine( forward, backward );
  140. //前置控制点
  141. shape.forward = this._drawForward( forward, index );
  142. //后置控制点
  143. shape.backward = this._drawBackward( backward, index );
  144. //vertex
  145. shape.vertex = this._drawVertex( point.getVertex(), index );
  146. },
  147. // 清理指定索引的图形点, 使得该点仅显示一个顶点
  148. _clearShapePoint: function ( index ) {
  149. var shape = this.pointShapes[ index ],
  150. // 当前的包含的数据点
  151. vertex = this.points[ index ].getVertex();
  152. shape.line.setPoint1( vertex.x, vertex.y ).setPoint2( vertex.x, vertex.y );
  153. shape.forward.setCenter( vertex.x, vertex.y );
  154. shape.backward.setCenter( vertex.x, vertex.y );
  155. this._stroke( shape.vertex, "white" );
  156. },
  157. // 根据指定的索引, 把该索引所对应的点更新成辅助点
  158. // 一个辅助点是当前曲线区间的起点, 它显示出该辅助点的forward控制点和连线
  159. _drawAssistPoint: function ( index ) {
  160. var shape = this.pointShapes[ index ],
  161. // 当前的包含的数据点
  162. bezierPoint = this.points[ index ],
  163. forward = bezierPoint.getForward(),
  164. vertex = bezierPoint.getVertex();
  165. shape.line.setPoint1( vertex.x, vertex.y ).setPoint2( forward.x, forward.y );
  166. shape.forward.setCenter( forward.x, forward.y );
  167. shape.backward.setCenter( vertex.x, vertex.y );
  168. this._stroke( shape.vertex, "white" );
  169. // 清理前一次的辅助点
  170. if ( index > 1 ) {
  171. this._clearShapePoint( index - 1 );
  172. }
  173. },
  174. _drawVertex: function ( vertex, index ) {
  175. var width = this.exterior.vertex.width,
  176. height = this.exterior.vertex.height,
  177. vertextRect = new Rect( width, height, vertex.x - width / 2 , vertex.y - height / 2 );
  178. //记录下图形
  179. this._stroke( vertextRect );
  180. this.addShape( vertextRect );
  181. GroupUtils.listenVertex( vertextRect, this, index );
  182. return vertextRect;
  183. },
  184. _drawForward: function ( point, index ) {
  185. var forwardPoint = this._drawControl( point );
  186. GroupUtils.listenForward( forwardPoint, this, index );
  187. return forwardPoint;
  188. },
  189. _drawBackward: function ( point, index ) {
  190. var backwardPoint = this._drawControl( point );
  191. GroupUtils.listenBackward( backwardPoint, this, index );
  192. return backwardPoint;
  193. },
  194. _drawControl: function ( point ) {
  195. var styles = this.exterior.control,
  196. radius = styles.radius,
  197. controlPoint = new Circle( radius, point.x, point.y );
  198. this._stroke( controlPoint );
  199. this.addShape( controlPoint );
  200. return controlPoint;
  201. },
  202. _drawLine: function ( forward, backward ) {
  203. var line = new Line ( forward.x, forward.y, backward.x, backward.y );
  204. line.stroke( new Pen( new Color( "#2d2d2d" ) ).setWidth( this.exterior.pen.width ) );
  205. this.addShape( line );
  206. return line;
  207. },
  208. _stroke: function ( shape, fillColor ) {
  209. shape.stroke( new Pen( new Color( "#2d2d2d" ) ).setWidth( this.exterior.pen.width ) );
  210. shape.fill( new Color( fillColor || "black" ) );
  211. }
  212. } );
  213. Utils.extend( PointGroup, {
  214. // 顶点类型常量
  215. TYPE_VERTEX: "vertex",
  216. TYPE_FORWARD: "forward",
  217. TYPE_BACKWARD: "backward"
  218. } );
  219. return PointGroup;
  220. } );