-
Notifications
You must be signed in to change notification settings - Fork 5
/
SVGPathEditor.min.js
15 lines (15 loc) · 12.9 KB
/
SVGPathEditor.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*!
* SVGPathEditor
* https://github.com/ynakajima/SVGPathEditor/
*
* Copyright (c) 2011, ynakajima <[email protected]>.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/(function(a){var b={};b.defineSetterGetter=function(a,b,c){!Object.prototype.__defineSetter__&&Object.defineProperty({},"x",{get:function(){return!0}}).x?Object.defineProperty(a,b,{set:c.setter,get:c.getter}):Object.prototype.__defineSetter__&&(a.__defineSetter__(b,c.setter),a.__defineGetter__(b,c.getter))},typeof a.ynakajima==="undefined"&&(a.ynakajima=b)})(this),function(a){var b=function(a,b,c,d,e){typeof e==="undefined"&&(e={isAbs:!0,isFollowNode:!0}),this.pathSeg=a,this.origPathSeg=a,this.pathSegList=b,this.index=c,this.sameNode=null,this.type=a.pathSegTypeAsLetter,this.isAbs=e.isAbs?!0:this.type.match(/^[A-Z]$/)!==null,this.isFollowNode=e.isFollowNode,this.svgPathSegList=d,this.x=null,this.y=null,this.x1=null,this.y1=null,this.x2=null,this.y2=null,this.init()};b.prototype.init=function(){var a=this.pathSeg,b=this.index-1<0?{x:0,y:0,type:""}:this.pathSegList[this.index-1];if(b.type.match(/^[Z]$/i))for(var c=2;this.index-c>=0;c++){b=this.pathSegList[this.index-c];if(this.index-c-1>=0&&this.pathSegList[this.index-c-1].origPathSeg.pathSegTypeAsLetter.match(/^[Z]$/i))break}var d=this.type,e=this.type.match(/^[A-Z]$/)!==null;d.match(/^[MLHVCSQT]$/i)&&(this.x=typeof a.x==="number"?e?a.x:b.x+a.x:b.x,this.y=typeof a.y==="number"?e?a.y:b.y+a.y:b.y,this.x1=typeof a.x1==="number"?e?a.x1:b.x+a.x1:null,this.y1=typeof a.y1==="number"?e?a.y1:b.y+a.y1:null,this.x2=typeof a.x2==="number"?e?a.x2:b.x+a.x2:null,this.y2=typeof a.y2==="number"?e?a.y2:b.y+a.y2:null),d.match(/^[S]$/i)?(this.x1=b.type.match(/^[CS]$/i)?b.x+(b.x-b.x2):b.x,this.y1=b.type.match(/^[CS]$/i)?b.y+(b.y-b.y2):b.y):d.match(/^[T]$/i)&&(this.x1=b.type.match(/^[QT]$/i)?b.x+(b.x-b.x1):b.x,this.y1=b.type.match(/^[QT]$/i)?b.y+(b.y-b.y1):b.y);if(this.isAbs&&!e){var f=document.createElementNS("http://www.w3.org/2000/svg","path"),g=null;switch(this.type){case"m":g=f.createSVGPathSegMovetoAbs(this.x,this.y);break;case"l":g=f.createSVGPathSegLinetoAbs(this.x,this.y);break;case"h":g=f.createSVGPathSegLinetoHorizontalAbs(this.x);break;case"v":g=f.createSVGPathSegLinetoVerticalAbs(this.y);break;case"c":g=f.createSVGPathSegCurvetoCubicAbs(this.x,this.y,this.x1,this.y1,this.x2,this.y2);break;case"s":g=f.createSVGPathSegCurvetoCubicSmoothAbs(this.x,this.y,this.x2,this.y2);break;case"q":g=f.createSVGPathSegCurvetoQuadraticAbs(this.x,this.y,this.x1,this.y1);break;case"t":g=f.createSVGPathSegCurvetoQuadraticSmoothAbs(this.x,this.y);break;default:g=null}g!=null&&(this.pathSeg=this.svgPathSegList.replaceItem(g,this.index),this.type=this.pathSeg.pathSegTypeAsLetter)}},b.prototype.setX=function(a){if(typeof this.pathSeg.x==="number"){var b=this.pathSeg.x;this.pathSeg.x=a;if(this.isFollowNode){var c=a-b,d=this.index==this.pathSegList.length-1?!1:this.pathSegList[this.index+1];d&&d.x1!=null&&d.setX1(d.pathSeg.x1+c),this.x2!=null&&(this.pathSeg.x2+=c)}this.init()}},b.prototype.setY=function(a){if(typeof this.pathSeg.y==="number"){var b=this.pathSeg.y;this.pathSeg.y=a;if(this.isFollowNode){var c=a-b,d=this.index==this.pathSegList.length-1?!1:this.pathSegList[this.index+1];d&&d.y1!=null&&d.setY1(d.pathSeg.y1+c),this.y2!=null&&(this.pathSeg.y2+=c)}this.init()}},b.prototype.setX1=function(a){typeof this.pathSeg.x1==="number"&&(this.pathSeg.x1=a,this.init())},b.prototype.setY1=function(a){typeof this.pathSeg.y1==="number"&&(this.pathSeg.y1=a,this.init())},b.prototype.setX2=function(a){typeof this.pathSeg.x2==="number"&&(this.pathSeg.x2=a,this.init())},b.prototype.setY2=function(a){typeof this.pathSeg.y2==="number"&&(this.pathSeg.y2=a,this.init())},a.ynakajima||(a.ynakajima={}),a.ynakajima.svg||(a.ynakajima.svg={}),a.ynakajima.svg.PathSeg=b}(window),function(a){var b="http://www.w3.org/2000/svg",c=function(a,b,c){typeof c!=="number"&&(c=""),this._x=null,this._y=null,this.pathSeg=a,this.targetCTM=b,this.xPropName="x"+c,this.yPropName="y"+c,this.origX=null,this.origY=null,this.origPageX=null,this.origPageY=null,this._isSelected=!1,this.isSelected=this._isSelected};ynakajima.defineSetterGetter(c.prototype,"isSelected",{setter:function(a){this._isSelected=a===!0},getter:function(){return this._isSelected}}),c.prototype.init=function(){},c.prototype.startDrag=function(a){this.origX=this.pathSeg.pathSeg[this.xPropName],this.origY=this.pathSeg.pathSeg[this.yPropName];var c=document.createElementNS(b,"svg").createSVGPoint();c.x=a.pageX,c.y=a.pageY,c=c.matrixTransform(this.targetCTM.inverse()),this.origPageX=c.x,this.origPageY=c.y},c.prototype.drag=function(a){var c=document.createElementNS(b,"svg").createSVGPoint();c.x=a.pageX,c.y=a.pageY,c=c.matrixTransform(this.targetCTM.inverse());var d=this.origX+(c.x-this.origPageX),e=this.origY+(c.y-this.origPageY);this._setX(d),this._setY(e)},c.prototype.stopDrag=function(){this.origX=null,this.origY=null,this.origPageX=null,this.origPageY=null},c.prototype._setX=function(a){this.xPropName==="x"?this.pathSeg.setX(a):this.xPropName==="x1"?this.pathSeg.setX1(a):this.xPropName==="x2"&&this.pathSeg.setX2(a)},c.prototype._setY=function(a){this.yPropName==="y"?this.pathSeg.setY(a):this.yPropName==="y1"?this.pathSeg.setY1(a):this.yPropName==="y2"&&this.pathSeg.setY2(a)},a.ynakajima||(a.ynakajima={}),a.ynakajima.svg||(a.ynakajima.svg={}),a.ynakajima.svg.DraggableControlPoint=c}(window),function(a){var b="http://www.w3.org/2000/svg",c=function(a,c){typeof c!="object"&&(c={isAbs:!0,editable:!0,isFollowNode:!0,targetRootLayer:null,editingRootLayer:null,pointLayer:null,lineLayer:null,editingPathStrokeColor:null,editingPointStrokeColor:null,editingPointStrokeWidth:null,editingPointFillColor:null}),this.targetElement=a,this.ownerSVGElement=a.ownerSVGElement,this._editable=!0,this.editable=typeof c.editable=="boolean"?c.editable:!0,this.isAbs=typeof c.isAbs=="boolean"?c.isAbs:!0,this._isFollowNode=!0,this.isFollowNode=typeof c.isFollowNode=="boolean"?c.isFollowNode:!0,this.CTM=null,this.editingPath=null,this.pathSegList=null,this.editingRootLayer=null,this.pointLayer=null,this.lineLayer=null,this.draggableControlPoints=null,this.selectedPoint=null;var d=document.createElementNS(b,"g");d.setAttribute("class","SVGPathEditor"),this.ownerSVGElement.appendChild(d),this.editingRootLayer=d,this.init(),this.renderControlPoints()};ynakajima.defineSetterGetter(c.prototype,"editable",{setter:function(a){this._editable=a===!0},getter:function(){return this._editable}}),ynakajima.defineSetterGetter(c.prototype,"isFollowNode",{setter:function(a){this._isFollowNode=a===!0;if(this.pathSegList!=null)for(var b=0,c=this.pathSegList.length;b<c;b++)this.pathSegList[b].isFollowNode=this._isFollowNode},getter:function(){return this._isFollowNode}}),c.prototype.init=function(){this.CTM=this.targetElement.getCTM();var a=document.createElementNS(b,"path");a.setAttribute("d",this.targetElement.getAttribute("d")),a.setAttribute("fill","none"),a.setAttribute("stroke","#00f"),a.setAttribute("stroke-width",.5/Math.max(this.CTM.a,this.CTM.d)),a.transform.baseVal.appendItem(a.transform.baseVal.createSVGTransformFromMatrix(this.CTM)),this.editingPath=a,this.initPathSegList();var c=this;this.editingRootLayer.addEventListener("mousedown",function(a){c._startDragHandler(a)},!1),this.ownerSVGElement.addEventListener("mousemove",function(a){c._dragHandler(a)},!1),this.ownerSVGElement.addEventListener("mouseup",function(a){c._stopDragHandler(a)},!1),this.editingRootLayer.addEventListener("mouseover",function(a){c.editable&&a.target.draggableControlPoint&&a.target.setAttribute("fill","#f00")},!1),this.editingRootLayer.addEventListener("mouseout",function(a){c.editable&&a.target.draggableControlPoint&&c.renderControlPoints()},!1)},c.prototype._startDragHandler=function(a){this.editable&&a.target.draggableControlPoint&&(a.target.draggableControlPoint.isSelected=!0,this.selectedPoint=a.target.draggableControlPoint,this.selectedPoint.startDrag(a),this.renderControlPoints())},c.prototype._dragHandler=function(a){this.editable&&this.selectedPoint!==null&&(this.selectedPoint.drag(a),this.updatePathSegList(),this.renderControlPoints())},c.prototype._stopDragHandler=function(a){this.editable&&this.selectedPoint!==null&&(this.selectedPoint.isSelected=!1,this.selectedPoint.stopDrag(),this.selectedPoint=null,this.targetElement.setAttribute("d",this.editingPath.getAttribute("d")),this.renderControlPoints())},c.prototype.initPathSegList=function(){this.pathSegList=[];var a=this.editingPath.pathSegList,b={isAbs:this.isAbs,isFollowNode:this.isFollowNode};for(var c=0,d=a.numberOfItems;c<a.numberOfItems;c++){var e=new ynakajima.svg.PathSeg(a.getItem(c),this.pathSegList,c,a,b);this.pathSegList.push(e)}this.targetElement.setAttribute("d",this.editingPath.getAttribute("d"))},c.prototype.updatePathSegList=function(){for(var a=0,b=this.pathSegList.length;a<b;a++)this.pathSegList[a].init()},c.prototype.renderControlPoints=function(){this.draggableControlPoints==null&&(this.draggableControlPoints=[]);var a=this.CTM,c=document.createElementNS(b,"g");c.setAttribute("class","lineLayer");var d=document.createElementNS(b,"g");d.setAttribute("class","pointLayer"),c.appendChild(this.editingPath);var e=this.pathSegList;for(var f=0,g=e.length;f<g;f++){var h=e[f],i=f+1<g?e[f+1]:null,j=f!==0?e[f-1]:{x:0,y:0};if(h.type.match(/^[Z]$/i))continue;var k=typeof this.draggableControlPoints[f]!="undefined",l=k&&this.draggableControlPoints[f].node.isSelected,m=k&&this.draggableControlPoints[f].c1&&this.draggableControlPoints[f].c1.isSelected,n=k&&this.draggableControlPoints[f].c2&&this.draggableControlPoints[f].c2.isSelected,o=l?"#f00":"#fff",p=m?"#f00":"#33f",q=n?"#f00":"#33f",r=this.ownerSVGElement.createSVGPoint();r.x=h.x,r.y=h.y,r=r.matrixTransform(a);var s=this.ownerSVGElement.createSVGPoint();s.x=j.x,s.y=j.y,s=s.matrixTransform(a);var t=document.createElementNS(b,"rect");t.setAttribute("x",r.x-3),t.setAttribute("y",r.y-3),t.setAttribute("width",6),t.setAttribute("height",6),t.setAttribute("fill",o),t.setAttribute("stroke","#000"),t.setAttribute("stroke-width","1"),t.setAttribute("opacity",1),i&&i.type.match(/^[ST]$/i)&&t.setAttribute("transform","rotate(45,"+r.x+","+r.y+")");var u;typeof this.draggableControlPoints[f]=="undefined"?(u=new ynakajima.svg.DraggableControlPoint(h,a,""),this.draggableControlPoints[f]={node:u}):u=this.draggableControlPoints[f].node,t.draggableControlPoint=u;if(h.x1!==null&&h.y1!==null){var v=this.ownerSVGElement.createSVGPoint();v.x=h.x1,v.y=h.y1,v=v.matrixTransform(a);var w=document.createElementNS(b,"circle");w.setAttribute("cx",v.x),w.setAttribute("cy",v.y),w.setAttribute("r",3),w.setAttribute("fill",p),w.setAttribute("stroke","#fff"),w.setAttribute("stroke-width","1"),h.type.match(/^[ST]$/i)&&(w.setAttribute("r",1),w.setAttribute("fill","#000")),d.appendChild(w);if(h.x2==null&&h.y2==null){var x=document.createElementNS(b,"path");x.setAttribute("d","M "+s.x+","+s.y+" L "+v.x+","+v.y+" "+r.x+","+r.y),x.setAttribute("stroke","#00f"),x.setAttribute("stroke-width",.5),x.setAttribute("fill","none"),c.appendChild(x)}var y;typeof this.draggableControlPoints[f].c1=="undefined"?(y=new ynakajima.svg.DraggableControlPoint(h,a,1),this.draggableControlPoints[f].c1=y):y=this.draggableControlPoints[f].c1,w.draggableControlPoint=y}if(h.x1!==null&&h.y1!==null&&h.x2!==null&&h.y2!==null){var z=this.ownerSVGElement.createSVGPoint();z.x=h.x2,z.y=h.y2,z=z.matrixTransform(a);var A=document.createElementNS(b,"circle");A.setAttribute("cx",z.x),A.setAttribute("cy",z.y),A.setAttribute("r",3),A.setAttribute("fill",q),A.setAttribute("stroke","#fff"),A.setAttribute("stroke-width",1),d.appendChild(A);var x=document.createElementNS(b,"path");x.setAttribute("d","M "+s.x+" "+s.y+" L "+v.x+" "+v.y+" M "+z.x+" "+z.y+" L "+r.x+" "+r.y),x.setAttribute("stroke","#00f"),x.setAttribute("stroke-width",.5),x.setAttribute("fill","none"),c.appendChild(x);var B;typeof this.draggableControlPoints[f].c2=="undefined"?(B=new ynakajima.svg.DraggableControlPoint(h,a,2),this.draggableControlPoints[f].c2=B):B=this.draggableControlPoints[f].c2,A.draggableControlPoint=B}d.appendChild(t)}this.clearControlPoints(),this.editingRootLayer.appendChild(c),this.editingRootLayer.appendChild(d),this.lineLayer=c,this.pointLayer=d},c.prototype.clearControlPoints=function(){var a=document.createElementNS(b,"g");a.setAttribute("class","lineLayer");var c=document.createElementNS(b,"g");c.setAttribute("class","pointLayer"),this.lineLayer&&this.lineLayer.parentNode&&this.lineLayer.parentNode.removeChild(this.lineLayer),this.pointLayer&&this.pointLayer.parentNode&&this.pointLayer.parentNode.removeChild(this.pointLayer),this.lineLayer=a,this.pointLayer=c},a.ynakajima||(a.ynakajima={}),a.ynakajima.svg||(a.ynakajima.svg={}),a.ynakajima.svg.SVGPathEditor=c}(window)