// Fireworks AutoShape // Description: Well known geometry based design guides. // Install by copying to Fireworks/Configuration/AutoShapes/ // Run in Fireworks via the Window > AutoShapes // Aaron Beall - http://abeall.com // Version 1.1 /* TODO: - alt drag corner nodes to perform symetrical scale - ? add top, left, right, bottom, top rightt, bottom left nodes BUGS: - [FIXED v1.1] on document reload, resizing fails to redraw */ var dom = fw.getDocumentDOM(); // vars var mouse = smartShape.currentMousePos; var cps = smartShape.elem.controlPoints; var data = smartShape.elem.customData; var elems = smartShape.elem.elements; var CP_PADDING = 10; var GUIDES = { half:[{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.001557632398753894},{x:0.998960498960499,y:0.9984423676012462}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.9984423676012462},{x:0.998960498960499,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.5},{x:0.998960498960499,y:0.5}]},{isClosed:false,opacity:100,n:[{x:0.5,y:0.9984423676012462},{x:0.5,y:0.001557632398753894}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]}], thirds:[{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.6682242990654206},{x:0.998960498960499,y:0.6682242990654206}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.3348909657320872},{x:0.998960498960499,y:0.3348909657320872}]},{isClosed:false,opacity:100,n:[{x:0.6663201663201663,y:0.9984423676012462},{x:0.6663201663201663,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.33367983367983367,y:0.9984423676012462},{x:0.33367983367983367,y:0.001557632398753894}]}], quarts:[{isClosed:true,opacity:100,n:[{x:0.998960498960499,y:0.5},{x:0.5,y:0.001557632398753894},{x:0.0010395010395010396,y:0.5},{x:0.5,y:0.9984423676012462}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.001557632398753894},{x:0.998960498960499,y:0.9984423676012462}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.9984423676012462},{x:0.998960498960499,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.7492211838006231},{x:0.998960498960499,y:0.7492211838006231}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.2507788161993769},{x:0.998960498960499,y:0.2507788161993769}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.5},{x:0.998960498960499,y:0.5}]},{isClosed:false,opacity:100,n:[{x:0.7494802494802495,y:0.9984423676012462},{x:0.7494802494802495,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.2505197505197505,y:0.9984423676012462},{x:0.2505197505197505,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.5,y:0.9984423676012462},{x:0.5,y:0.001557632398753894}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]}], root5:[{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.7242990654205608},{x:0.998960498960499,y:0.7242990654205608}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.2757009345794392},{x:0.998960498960499,y:0.2757009345794392}]},{isClosed:false,opacity:100,n:[{x:0.7203742203742204,y:0.9984423676012462},{x:0.7203742203742204,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.27754677754677753,y:0.9984423676012462},{x:0.27754677754677753,y:0.001557632398753894}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]}], golden:[{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.618380062305296},{x:0.998960498960499,y:0.618380062305296}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.38161993769470404},{x:0.998960498960499,y:0.38161993769470404}]},{isClosed:false,opacity:100,n:[{x:0.6185031185031185,y:0.9984423676012462},{x:0.6185031185031185,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.3814968814968815,y:0.9984423676012462},{x:0.3814968814968815,y:0.001557632398753894}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]}], goldenderiv1:[{isClosed:false,opacity:100,n:[{x:0.19230769230769232,y:0.8084112149532711},{x:0.0010395010395010396,y:0.9984423676012462}]},{isClosed:false,opacity:100,n:[{x:0.8076923076923077,y:0.8084112149532711},{x:0.998960498960499,y:0.9984423676012462}]},{isClosed:false,opacity:100,n:[{x:0.8076923076923077,y:0.19158878504672897},{x:0.998960498960499,y:0.001557632398753894}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.001557632398753894},{x:0.19230769230769232,y:0.19158878504672897}]},{isClosed:false,opacity:25.098039215686274,n:[{x:0.6912681912681913,y:0.3099688473520249},{x:0.5,y:0.8084112149532711},{x:0.3087318087318087,y:0.3099688473520249}]},{isClosed:false,opacity:25.098039215686274,n:[{x:0.6912681912681913,y:0.6900311526479751},{x:0.5,y:0.19158878504672897},{x:0.3087318087318087,y:0.6900311526479751}]},{isClosed:false,opacity:25.098039215686274,n:[{x:0.3087318087318087,y:0.6900311526479751},{x:0.8076923076923077,y:0.5},{x:0.3087318087318087,y:0.3099688473520249}]},{isClosed:false,opacity:25.098039215686274,n:[{x:0.6912681912681913,y:0.6900311526479751},{x:0.19230769230769232,y:0.5},{x:0.6912681912681913,y:0.3099688473520249}]},{isClosed:false,opacity:100,n:[{x:0.8076923076923077,y:0.5},{x:0.998960498960499,y:0.5}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.5},{x:0.19230769230769232,y:0.5}]},{isClosed:false,opacity:100,n:[{x:0.5,y:0.9984423676012462},{x:0.5,y:0.8084112149532711}]},{isClosed:false,opacity:100,n:[{x:0.5,y:0.19158878504672897},{x:0.5,y:0.001557632398753894}]},{isClosed:true,opacity:100,n:[{x:0.3804573804573805,y:0.38006230529595014},{x:0.6195426195426196,y:0.38006230529595014},{x:0.6195426195426196,y:0.6199376947040498},{x:0.3804573804573805,y:0.6199376947040498}]},{isClosed:true,opacity:100,n:[{x:0.3076923076923077,y:0.308411214953271},{x:0.6923076923076923,y:0.308411214953271},{x:0.6923076923076923,y:0.6915887850467289},{x:0.3076923076923077,y:0.6915887850467289}]},{isClosed:true,opacity:100,n:[{x:0.19126819126819128,y:0.19003115264797507},{x:0.8087318087318087,y:0.19003115264797507},{x:0.8087318087318087,y:0.8099688473520249},{x:0.19126819126819128,y:0.8099688473520249}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:1},{x:0,y:1}]}], goldenderiv2:[{isClosed:false,opacity:100,n:[{x:0.18814968814968816,y:0.0015552099533437014},{x:0.5,y:0.8055987558320373},{x:0.8118503118503119,y:0.0015552099533437014}]},{isClosed:false,opacity:100,n:[{x:0.18814968814968816,y:0.9968895800933126},{x:0.5,y:0.19279743390357698},{x:0.8118503118503119,y:0.9968895800933126}]},{isClosed:true,opacity:100,n:[{x:0.998960498960499,y:0.49922239502332816},{x:0.8118503118503119,y:0.9968895800933126},{x:0.0010395010395010396,y:0.49922239502332816},{x:0.8118503118503119,y:0.0015552099533437014}]},{isClosed:true,opacity:100,n:[{x:0.0010395010395010396,y:0.49922239502332816},{x:0.18814968814968816,y:0.9968895800933126},{x:0.998960498960499,y:0.49922239502332816},{x:0.18814968814968816,y:0.0015552099533437014}]},{isClosed:true,opacity:100,n:[{x:0,y:0},{x:1,y:0},{x:1,y:0.9984447900466563},{x:0,y:0.9984447900466563}]},{isClosed:false,opacity:100,n:[{x:0.0010395010395010396,y:0.49922239502332816},{x:0.998960498960499,y:0.49922239502332816}]},{isClosed:false,opacity:100,n:[{x:0.8118503118503119,y:1},{x:0.8118503118503119,y:0.0015552099533437014}]},{isClosed:false,opacity:100,n:[{x:0.18814968814968816,y:1},{x:0.18814968814968816,y:0.0015552099533437014}]},{isClosed:false,opacity:100,n:[{x:0.5,y:0.9968895800933126},{x:0.5,y:0.0015552099533437014}]}] } // reload if(data.guideName) data.guide = GUIDES[data.guideName]; // operations var operation = new Object(); // create operation.InsertSmartShapeAt = function(){ // default settings var width = 300, height = 200; data.shapeName = "geometry guides"; data.guideName = fw.GeometryGuidesAutoShape_lastShape||"golden"; data.guide = GUIDES[data.guideName]; // setup control points cps.length = 10; SetControlPoint(cps[0], AddPoints(mouse, {x:-width/2, y:-height/2}), "corner", "Corner; Shift to maintain aspect ratio"); SetControlPoint(cps[1], AddPoints(mouse, {x:width/2, y:height/2}), "size", "Resize; Shift to maintain aspect ratio"); SetControlPoint(cps[2], mouse, "ratio", "Ratio:"+(width/height)); cps[2].type = 'crossHair'; SetControlPoint(cps[3], AddPoints(mouse, {x:-width/2 + CP_PADDING, y:-height/2 - CP_PADDING}), "half", "Half"); SetControlPoint(cps[4], AddPoints(mouse, {x:-width/2 + CP_PADDING*2, y:-height/2 - CP_PADDING}), "thirds", "Thirds"); SetControlPoint(cps[5], AddPoints(mouse, {x:-width/2 + CP_PADDING*3, y:-height/2 - CP_PADDING}), "quarts", "Quarts"); SetControlPoint(cps[6], AddPoints(mouse, {x:-width/2 + CP_PADDING*4, y:-height/2 - CP_PADDING}), "root5", "Root5"); SetControlPoint(cps[7], AddPoints(mouse, {x:-width/2 + CP_PADDING*5, y:-height/2 - CP_PADDING}), "golden", "Golden"); SetControlPoint(cps[8], AddPoints(mouse, {x:-width/2 + CP_PADDING*6, y:-height/2 - CP_PADDING}), "goldenderiv1", "Golden Derivates 1"); SetControlPoint(cps[9], AddPoints(mouse, {x:-width/2 + CP_PADDING*7, y:-height/2 - CP_PADDING}), "goldenderiv2", "Golden Derivates 2"); // init createGuide(); updateControlPoints(); // show selected guide cpt(data.guideName).type = 'defaultInverted'; } // start dragging control point operation.BeginDragControlPoint = function(){ data._click = true; var parms = smartShape.GetDefaultMoveParms(); var cp = smartShape.currentControlPoint; switch(cp.name){ case 'corner': case 'size': //parms.constrain45Key = 'shiftKey'; data._cp = {x:cp.x,y:cp.y}; cp.RegisterMove(parms); smartShape.getsDragEvents = true; break; } } // dragging control point operation.DragControlPoint = function(){ data._click = false; var cp = smartShape.currentControlPoint; switch(cp.name){ // resizing case 'corner': case 'size': if(smartShape.shiftKeyDown){ var xdif = cp.x-data._cp.x, ydif = cp.y-data._cp.y, p; var c = cp.name == 'size' ? cpt('corner') : cpt('size'); if(Math.abs(xdif) > Math.abs(ydif)){ p = (cp.x-c.x)/(data._cp.x-c.x); cp.y = (data._cp.y-c.y)*p + c.y; }else{ p = (cp.y-c.y)/(data._cp.y-c.y); cp.x = (data._cp.x-c.x)*p + c.x; } drawGuide(); }else{ drawGuide(); } updateControlPoints(); break; } } // release control point operation.EndDragControlPoint = function(){ var cp = smartShape.currentControlPoint; switch(cp.name){ case 'corner': // resizing via corner if(data._click){ // corner clicked, use numeric input var input = prompt('Enter the new corner coordinates, formatted as "X,Y"',cpt('corner').x+','+cpt('corner').y); if(input == null) break; input = input.split(','); if(input.length != 2 || isNaN(Number(input[0])) || isNaN(Number(input[1]))) break; cpt('corner').x = Number(input[0]); cpt('corner').y = Number(input[1]); } drawGuide(); case 'size': // resizing via size control point if(data._click){ // clicked, use numeric input var input = prompt('Enter the new size, formatted as "Width,Height"',cpt('size').x+','+cpt('size').y); if(input == null) break; input = input.split(','); if(input.length != 2 || isNaN(Number(input[0])) || isNaN(Number(input[1]))) break; cpt('size').x = Number(input[0]); cpt('size').y = Number(input[1]); } drawGuide(); break; case 'ratio': // resizing via setting the ratio var input = prompt('Enter a new width-to-height ratio, formatted as a decimal(example: "1.5"), or a fraction(example: "3:2").',((cpt('size').x-cpt('corner').x)/(cpt('size').y-cpt('corner').y))); if(input == null) break; if(isNaN(Number(input))){ input = input.split(':'); if(input.length != 2 || isNaN(Number(input[0])) || isNaN(Number(input[1]))) break; input = Number(input[0])/Number(input[1]); } cpt('size').y = cpt('corner').y + ((cpt('size').x-cpt('corner').x)/input); drawGuide(); break; default: // switching the active guide if(cp.name != data.guideName){ cpt(data.guideName).type = 'default'; data.guideName = cp.name; cpt(data.guideName).type = 'defaultInverted'; data.guide = GUIDES[data.guideName]; createGuide(); fw.GeometryGuidesAutoShape_lastShape = data.guideName; } break; } updateControlPoints(); } // node helper functions SetNodePosition = function(node, pt){ SetBezierNodePosition(node,pt,pt,pt); } SetBezierNodePosition = function(node, ptp, pt, pts){ node.predX = ptp.x; node.predY = ptp.y; node.x = pt.x; node.y = pt.y; node.succX = pts.x; node.succY = pts.y; } SetControlPoint = function(cp, pt, name, toolTip){ cp.x = pt.x; cp.y = pt.y; cp.name = name; cp.toolTip = toolTip; } AddPoints = function(pt1, pt2){ return {x:pt1.x + pt2.x, y:pt1.y + pt2.y}; } // execute operation if (operation[smartShape.operation]) operation[smartShape.operation](); // create a new guide function createGuide(){ var guide = data.guide; elems.length = 0; for(var e=0; e