123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- /*
- * PS 钢笔工具 控制逻辑
- */
- define( function ( require, exports, module ) {
- // 资源引入
- var Bezier = require( "graphic/bezier" ),
- Color = require( "graphic/color" ),
- Pen = require( "graphic/pen" ),
- Utils = require( "core/utils" ),
- Vector = require( "graphic/vector" ),
- // 引入可绘制的点集合
- PointGroup = require( "../ps-pen/demo.pointgroup" ),
- BezierPoint = require( "graphic/bezierpoint" );
- function Controller ( paper ) {
- this.paper = paper || null;
- this.bezier = null;
- this.bezierPoints = null;
- this.pointGroup = null;
- this.drawState = false;
- // 记录当前是否处于更新状态
- this.modifyState = false;
- // 记录更新状态的持久信息
- this._modifyStatus = null;
- // 允许重新拖动编辑的
- this.editable = false;
- }
- Utils.extend( Controller.prototype, {
- takeover: function ( paper ) {
- paper && ( this.paper = paper );
- initListener( this );
- },
- enableDraw: function () {
- this.drawState = true;
- },
- disableDraw: function () {
- this.drawState = false;
- },
- enableModify: function () {
- this.modifyState = true;
- },
- disableModify: function () {
- this.modifyState = false;
- },
- // 设置更新状态
- setModifyStatus: function ( status ) {
- this._modifyStatus = status;
- },
- clearModifySatus: function () {
- this._modifyStatus = null;
- },
- getModifyStatus: function () {
- return this._modifyStatus;
- },
- enableEdit: function () {
- this.editable = true;
- },
- disableEdit: function () {
- this.editable = false;
- },
- setBezier: function ( bezier ) {
- this.bezier = bezier;
- this.bezierPoints = [];
- return this;
- },
- getBezier: function () {
- return this.bezier;
- },
- setPointGroup: function ( pointGroup ) {
- this.pointGroup = pointGroup;
- return this;
- },
- getPointGroup: function () {
- return this.pointGroup;
- },
- addPoint: function ( point ) {
- this.bezierPoints && this.bezierPoints.push( point );
- return this;
- },
- getPoints: function () {
- return this.bezierPoints;
- }
- } );
- return Controller;
- // 私有方法实现
- // 初始化交互事件监听器
- function initListener ( controller ) {
- // 记录是否允许所有事件的监听
- var isBegin = false,
- // 记录是否需要更新曲线
- isUpdateable = false,
- paper = controller.paper,
- currentBezier = null,
- currentPointGroup = null;
- paper.on( "mousedown", function ( e ) {
- var point = null;
- e.preventDefault();
- if ( !controller.drawState ) {
- return;
- }
- // 切换监听状态
- if ( !isBegin ) {
- isBegin = true;
- currentBezier = createBezier( paper );
- currentPointGroup = createPointGroup( paper );
- listenPointGroup( currentPointGroup, controller );
- //设置当前controller处理的贝塞尔曲线
- controller.setBezier( currentBezier );
- controller.setPointGroup( currentPointGroup );
- }
- isUpdateable = false;
- // 获取当前鼠标点击在用户坐标系上的映射点
- point = e.getPosition();
- updateBezier( controller, point );
- } );
- // 绘制时 更新控制点
- paper.on( "mousemove", function ( e ) {
- var point = null,
- bezierPoint = null;
- e.preventDefault();
- if ( !controller.drawState ) {
- return;
- }
- if ( !isBegin || isUpdateable ) {
- return;
- }
- point = e.getPosition();
- currentBezier.getLastPoint().setForward( point.x, point.y );
- currentPointGroup.getLastPoint().setForward( point.x, point.y );
- } );
- // 编辑时拖动更新
- paper.on( "mousemove", function ( e ) {
- var mousePoint = null,
- currentPoint = null,
- pointIndex = -1;
- e.preventDefault();
- // 不可编辑
- if ( !controller.editable ) {
- return;
- }
- mousePoint = e.getPosition();
- pointIndex = controller._modifyStatus.pointIndex;
- currentPoint = currentPointGroup.getPointByIndex( pointIndex );
- switch ( controller._modifyStatus.pointType ) {
- case PointGroup.TYPE_FORWARD:
- currentPoint.setForward( mousePoint.x, mousePoint.y );
- currentBezier.getPoint( pointIndex ).setForward( mousePoint.x, mousePoint.y );
- break;
- case PointGroup.TYPE_BACKWARD:
- currentPoint.setBackward( mousePoint.x, mousePoint.y );
- currentBezier.getPoint( pointIndex ).setBackward( mousePoint.x, mousePoint.y );
- break;
- case PointGroup.TYPE_VERTEX:
- currentPoint.moveTo( mousePoint.x, mousePoint.y );
- currentBezier.getPoint( pointIndex ).moveTo( mousePoint.x, mousePoint.y );
- break;
- }
- } );
- paper.on( "mouseup", function () {
- if ( controller.drawState ) {
- isUpdateable = isBegin;
- } else if ( controller.modifyState ) {
- controller.disableEdit();
- // 清空状态
- controller.clearModifySatus();
- }
- } );
- }
- // 画贝塞尔曲线
- function updateBezier ( controller, point ) {
- var bezierPoint = new BezierPoint( point.x, point.y, true );
- //添加可绘制控制点
- controller.getPointGroup().addPoint( bezierPoint.clone() );
- //记录贝塞尔的控制点
- controller.addPoint( bezierPoint );
- //更新贝塞尔曲线的点
- controller.getBezier().setPoints( controller.getPoints() );
- }
- // 创建一个新的贝塞尔
- function createBezier ( paper ) {
- var bezier = new Bezier();
- bezier.stroke( new Pen( new Color( "black" ) ).setWidth( 100 ) );
- paper.addShape( bezier );
- return bezier;
- }
- function createPointGroup ( paper ) {
- var pointGroup = new PointGroup();
- paper.addShape( pointGroup );
- return pointGroup;
- }
- // 监听点上的事件
- function listenPointGroup ( pointGroup, controller ) {
- pointGroup.on( "pointmousedown", function ( e ) {
- var currentPoint = null,
- currentType = null,
- index = -1,
- vertexWidth = 0;
- // 非modify状态, 不处理
- if ( !controller.modifyState ) {
- return;
- }
- index = e.targetPointIndex;
- currentType = e.targetPointType;
- currentPoint = pointGroup.getPointByIndex( index );
- // 获取到当前顶点的宽度
- vertexWidth = pointGroup.getVertexWidth();
- // 检查当前点击的点的控制点是否和顶点重叠
- // 如果重叠了, 则认为点击是发生在forward的控制点上的
- if ( currentType === PointGroup.TYPE_VERTEX ) {
- //更新点类型
- switch ( checkOverlapping( currentPoint, vertexWidth ) ) {
- case 1:
- currentType = PointGroup.TYPE_FORWARD;
- break;
- case 2:
- currentType = PointGroup.TYPE_BACKWARD
- break;
- }
- }
- // 运行更新
- controller.enableEdit();
- controller.setModifyStatus( {
- pointType: currentType,
- pointIndex: index
- } );
- //更新当前的点
- this.selectPoint( index );
- } );
- }
- // 工具方法, 检测贝塞尔曲线上的点的控制点和顶点是否重叠在一起
- // 参数distance控制了点之间的最小距离, 如果不大于该距离, 则认为是重叠的
- // 返回值有: 0: 无重叠, 1: forward重叠, 2: backward重叠
- function checkOverlapping ( bezierPoint, distance ) {
- var forward = bezierPoint.getForward(),
- backward = bezierPoint.getBackward(),
- vertex = bezierPoint.getVertex();
- if ( Vector.fromPoints( forward, vertex ).length() <= distance ) {
- // forward重叠
- return 1;
- } else if ( Vector.fromPoints( backward, vertex ).length() <= distance ) {
- // backward重叠
- return 2;
- }
- // 无重叠
- return 0;
- }
- } );
|