|  |  | 
 |  |  |  */ | 
 |  |  |  | 
 |  |  | methodDraw.addExtension("shapes", function() { | 
 |  |  |    | 
 |  |  |  | 
 |  |  |  | 
 |  |  |   var current_d, cur_shape_id; | 
 |  |  |   var canv = methodDraw.canvas; | 
 |  |  | 
 |  |  |   var start_x, start_y; | 
 |  |  |   var svgroot = canv.getRootElem(); | 
 |  |  |   var lastBBox = {}; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   // This populates the category list | 
 |  |  |   var categories = { | 
 |  |  |     basic: 'Basic', | 
 |  |  | 
 |  |  |     ui: 'User Interface', | 
 |  |  |     social: 'Social Web' | 
 |  |  |   }; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   var library = { | 
 |  |  |     'basic': { | 
 |  |  |       data: { | 
 |  |  | 
 |  |  |         'heart': 'm150,73c61,-175 300,0 0,225c-300,-225 -61,-400 0,-225z', | 
 |  |  |         "cylinder": "m299.0007,83.77844c0,18.28676 -66.70958,33.11111 -149.00002,33.11111m149.00002,-33.11111l0,0c0,18.28676 -66.70958,33.11111 -149.00002,33.11111c-82.29041,0 -148.99997,-14.82432 -148.99997,-33.11111m0,0l0,0c0,-18.28674 66.70956,-33.1111 148.99997,-33.1111c82.29044,0 149.00002,14.82436 149.00002,33.1111l0,132.44449c0,18.28674 -66.70958,33.11105 -149.00002,33.11105c-82.29041,0 -148.99997,-14.82431 -148.99997,-33.11105z", | 
 |  |  |         "arrow_up": "m1.49805,149.64304l148.50121,-148.00241l148.50121,148.00241l-74.25061,0l0,148.71457l-148.5012,0l0,-148.71457z", | 
 |  |  |         "arrow_u_turn": "m1.00059,299.00055l0,-167.62497l0,0c0,-72.00411 58.37087,-130.37499 130.375,-130.37499l0,0l0,0c34.57759,0 67.73898,13.7359 92.18906,38.18595c24.45006,24.45005 38.18593,57.61144 38.18593,92.18904l0,18.625l37.24997,0l-74.49995,74.50002l-74.50002,-74.50002l37.25,0l0,-18.625c0,-30.8589 -25.0161,-55.87498 -55.87498,-55.87498l0,0l0,0c-30.85892,0 -55.875,25.01608 -55.875,55.87498l0,167.62497z", | 
 |  |  |         "arrow_left_up": "m0.99865,224.5l74.50004,-74.5l0,37.25l111.74991,0l0,-111.75l-37.25,0l74.5,-74.5l74.5,74.5l-37.25,0l0,186.25l-186.24989,0l0,37.25l-74.50005,-74.5z", | 
 |  |  |         "piping_left": "m61.06297,135.21906c1.26516,30.57214 1.45736,47.83058 49.70693,48.17825c48.24958,0.34766 84.79024,-0.96742 117.29734,-2.05798c32.5071,-1.09057 42.57196,-6.82504 39.75187,-89.83523l29.71009,-0.09174c4.15832,110.21703 -16.27162,115.96341 -62.08326,119.84398c-45.81163,3.88059 -122.9577,2.75494 -155.18351,0.85096c-32.2258,-1.90396 -49.88012,-29.62204 -49.71715,-67.06613c0.16297,-37.4441 -12.64439,-27.42789 -29.18351,-30.51291l-0.30561,-24.87842c49.64155,-5.12952 58.74164,14.99708 60.0068,45.56922l0,-0.00002l0.00001,0.00001l0,0.00001z", | 
 |  |  |         "piping_right": "m34.77162,144.78038c1.93502,23.59007 0.90063,36.98668 51.7728,39.12084c50.87217,2.13416 49.3661,0.20868 95.80745,0.31737c46.44135,0.10868 46.80596,-16.26537 50.39204,-41.13127c3.58607,-24.8659 9.89537,-41.12805 16.9583,-45.07714c7.06293,-3.94908 26.20271,-3.41801 47.83801,-1.96183l-0.56549,21.42594c-1.95665,3.6252 -32.45161,-7.98981 -32.68677,30.50966c-0.23516,38.49947 -15.74948,61.56741 -84.43714,63.72421c-68.68766,2.15681 -34.0838,1.55507 -97.51854,-0.36787c-63.43474,-1.92294 -79.51644,-17.24319 -79.3467,-58.58433c0.16974,-41.34115 0.12119,-45.63576 -0.32767,-49.13504l30.73149,0.18025c0.17338,20.1933 -0.5528,17.38914 1.38222,40.97921z", | 
 |  |  |         "curve_1": "m12.99218,75.18742c-21.79909,161.7324 270.03537,128.87978 281.3936,129.5404", | 
 |  |  |         "curve_2": "m9.70598,97.53259c60.4983,112.24893 204.38633,128.61647 275.93837,-0.52493", | 
 |  |  |         "S-shaped_arc": "m177.40301,7.84547c-107.70811,-0.87963 -95.07584,134.96412 -25.7545,143.11086c69.32135,8.14675 89.64716,119.18795 -27.73838,144.46005", | 
 |  |  |         "anti_S-shaped_arc": "m133.54237,3.90583c113.54352,-2.11252 100.59557,128.86359 8.96395,144.70747c-91.63162,15.84388 -77.68768,149.98876 37.54903,146.81995", | 
 |  |  |         "plaque": "m-0.00197,49.94376l0,0c27.5829,0 49.94327,-22.36036 49.94327,-49.94327l199.76709,0l0,0c0,27.5829 22.36037,49.94327 49.94325,49.94327l0,199.7671l0,0c-27.58289,0 -49.94325,22.36034 -49.94325,49.94325l-199.76709,0c0,-27.58292 -22.36037,-49.94325 -49.94327,-49.94325z", | 
 |  |  |         "page": "m249.3298,298.99744l9.9335,-39.73413l39.73413,-9.93355l-49.66763,49.66768l-248.33237,0l0,-298.00001l298.00001,0l0,248.33234", | 
 |  |  |         "cross": "m0.99844,99.71339l98.71494,0l0,-98.71495l101.26279,0l0,98.71495l98.71495,0l0,101.2628l-98.71495,0l0,98.71494l-101.26279,0l0,-98.71494l-98.71494,0z", | 
 |  |  |         "divide": "m150,0.99785l0,0c25.17819,0 45.58916,20.41097 45.58916,45.58916c0,25.17821 -20.41096,45.58916 -45.58916,45.58916c-25.17822,0 -45.58916,-20.41093 -45.58916,-45.58916c0,-25.1782 20.41093,-45.58916 45.58916,-45.58916zm0,296.25203c-25.17822,0 -45.58916,-20.41095 -45.58916,-45.58917c0,-25.17819 20.41093,-45.58916 45.58916,-45.58916c25.17819,0 45.58916,20.41096 45.58916,45.58916c0,25.17822 -20.41096,45.58917 -45.58916,45.58917zm-134.06754,-193.71518l268.13507,0l0,91.17833l-268.13507,0z", | 
 |  |  |         "minus": "m0.99887,102.39503l297.49445,0l0,95.2112l-297.49445,0z", | 
 |  |  |         "times": "m1.00089,73.36786l72.36697,-72.36697l76.87431,76.87368l76.87431,-76.87368l72.36765,72.36697l-76.87433,76.87431l76.87433,76.87431l-72.36765,72.36765l-76.87431,-76.87433l-76.87431,76.87433l-72.36697,-72.36765l76.87368,-76.87431l-76.87368,-76.87431z" | 
 |  |  |          | 
 |  |  |  | 
 |  |  |  | 
 |  |  |       }, | 
 |  |  |       buttons: [] | 
 |  |  |     } | 
 |  |  |   }; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   var cur_lib = library.basic; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   var mode_id = 'shapelib'; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   function loadIcons() { | 
 |  |  |     $('#shape_buttons').empty(); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     // Show lib ones | 
 |  |  |     $('#shape_buttons').append(cur_lib.buttons); | 
 |  |  |   } | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   function loadLibrary(cat_id) { | 
 |  |  |    | 
 |  |  |  | 
 |  |  |     var lib = library[cat_id]; | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     if(!lib) { | 
 |  |  |       $('#shape_buttons').html('Loading...'); | 
 |  |  |       $.getJSON('extensions/shapelib/' + cat_id + '.json', function(result, textStatus) { | 
 |  |  | 
 |  |  |       }); | 
 |  |  |       return; | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     cur_lib = lib; | 
 |  |  |     if(!lib.buttons.length) makeButtons(cat_id, lib); | 
 |  |  |     loadIcons(); | 
 |  |  |   } | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   function makeButtons(cat, shapes) { | 
 |  |  |     var size = cur_lib.size || 300; | 
 |  |  |     var fill = cur_lib.fill || false; | 
 |  |  |     var off = size * .05; | 
 |  |  |     var vb = [-off, -off, size + off*2, size + off*2].join(' '); | 
 |  |  |     var stroke = fill ? 0: (size/30); | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     var shape_icon = new DOMParser().parseFromString( | 
 |  |  |       '<svg xmlns="http://www.w3.org/2000/svg"><svg viewBox="' + vb + '"><path fill="#333" stroke="transparent" stroke-width="' + stroke + '" /><\/svg><\/svg>', | 
 |  |  |       'text/xml'); | 
 |  |  | 
 |  |  |     shape_icon.documentElement.setAttribute('width', width); | 
 |  |  |     shape_icon.documentElement.setAttribute('height', height); | 
 |  |  |     var svg_elem = $(document.importNode(shape_icon.documentElement,true)); | 
 |  |  |    | 
 |  |  |  | 
 |  |  |     var data = shapes.data; | 
 |  |  |      | 
 |  |  |  | 
 |  |  |     cur_lib.buttons = []; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |     for(var id in data) { | 
 |  |  |       var path_d = data[id]; | 
 |  |  |       var icon = svg_elem.clone(); | 
 |  |  |       icon.find('path').attr('d', path_d); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var icon_btn = icon.wrap('<div class="tool_button">').parent().attr({ | 
 |  |  |         id: mode_id + '_' + id, | 
 |  |  |         title: id | 
 |  |  |       }); | 
 |  |  |        | 
 |  |  |        | 
 |  |  |  | 
 |  |  |  | 
 |  |  |       // Store for later use | 
 |  |  |       cur_lib.buttons.push(icon_btn[0]); | 
 |  |  |     } | 
 |  |  |      | 
 |  |  |  | 
 |  |  |   } | 
 |  |  |  | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   return { | 
 |  |  |     svgicons: "extensions/ext-shapes.xml", | 
 |  |  |     buttons: [{ | 
 |  |  |       id: "tool_shapelib", | 
 |  |  |       type: "mode_flyout", // _flyout | 
 |  |  |       position: 6, | 
 |  |  |       title: "Shape library", | 
 |  |  |       title: "形状库", | 
 |  |  |       icon: "extensions/ext-shapes.png", | 
 |  |  |       events: { | 
 |  |  |         "click": function() { | 
 |  |  | 
 |  |  |     }], | 
 |  |  |     callback: function() { | 
 |  |  |  | 
 |  |  |      | 
 |  |  |  | 
 |  |  |       var btn_div = $('<div id="shape_buttons">'); | 
 |  |  |       $('#tools_shapelib > *').wrapAll(btn_div); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var shower = $('#tools_shapelib_show'); | 
 |  |  |  | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       loadLibrary('basic'); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // Do mouseup on parent element rather than each button | 
 |  |  |       $('#shape_buttons').mouseup(function(evt) { | 
 |  |  |         var btn = $(evt.target).closest('div.tool_button'); | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         if(!btn.length) return; | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         var copy = btn.children().clone().attr({width: 24, height: 24}); | 
 |  |  |         shower.children(':not(.flyout_arrow_horiz)').remove(); | 
 |  |  |         shower | 
 |  |  | 
 |  |  |           .attr('data-curopt', '#' + btn[0].id) // This sets the current mode | 
 |  |  |           .mouseup(); | 
 |  |  |         canv.setMode(mode_id); | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         cur_shape_id = btn[0].id.substr((mode_id+'_').length); | 
 |  |  |         current_d = cur_lib.data[cur_shape_id]; | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         $('.tools_flyout').fadeOut(); | 
 |  |  |  | 
 |  |  |       }); | 
 |  |  |  | 
 |  |  | //       | 
 |  |  | // | 
 |  |  |       var shape_cats = $('<div id="shape_cats">'); | 
 |  |  |       var cat_str = ''; | 
 |  |  |        | 
 |  |  |       $.each(categories, function(id, label) { | 
 |  |  |         cat_str += '<div data-cat=' + id + '>' + label + '</div>'; | 
 |  |  |       }); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // $.each(categories, function(id, label) { | 
 |  |  |       //   cat_str += '<div data-cat=' + id + '>' + label + '</div>'; | 
 |  |  |       // }); | 
 |  |  |  | 
 |  |  |       shape_cats.html(cat_str).children().bind('mouseup', function() { | 
 |  |  |         var catlink = $(this); | 
 |  |  |         catlink.siblings().removeClass('current'); | 
 |  |  |         catlink.addClass('current'); | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         loadLibrary(catlink.attr('data-cat')); | 
 |  |  |         // Get stuff | 
 |  |  |          | 
 |  |  |  | 
 |  |  |         return false; | 
 |  |  |       }); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       shape_cats.children().eq(0).addClass('current'); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       $('#tools_shapelib').prepend(shape_cats); | 
 |  |  |  | 
 |  |  |       shower.mouseup(function() { | 
 |  |  |         canv.setMode(current_d ? mode_id : 'select'); | 
 |  |  |       }); | 
 |  |  |  | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       $('#tool_shapelib').remove(); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var h = $('#tools_shapelib').height(); | 
 |  |  |       $('#tools_shapelib').css({ | 
 |  |  |         'margin-top': -(h/2), | 
 |  |  |         'margin-left': 3 | 
 |  |  |       }); | 
 |  |  |  | 
 |  |  |    | 
 |  |  |  | 
 |  |  |     }, | 
 |  |  |     mouseDown: function(opts) { | 
 |  |  |       var mode = canv.getMode(); | 
 |  |  |       if(mode !== mode_id) return; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var e = opts.event; | 
 |  |  |       var x = start_x = opts.start_x; | 
 |  |  |       var y = start_y = opts.start_y; | 
 |  |  | 
 |  |  |         cur_shape.setAttribute('d', current_d); | 
 |  |  |         canv.pathActions.fixEnd(cur_shape); | 
 |  |  |       } | 
 |  |  |        | 
 |  |  |       cur_shape.setAttribute('transform', "translate(" + x + "," + y + ") scale(0.005) translate(" + -x + "," + -y + ")");       | 
 |  |  |  | 
 |  |  |       cur_shape.setAttribute('transform', "translate(" + x + "," + y + ") scale(0.005) translate(" + -x + "," + -y + ")"); | 
 |  |  | //      console.time('b'); | 
 |  |  |       canv.recalculateDimensions(cur_shape); | 
 |  |  |       var tlist = canv.getTransformList(cur_shape); | 
 |  |  | 
 |  |  |     mouseMove: function(opts) { | 
 |  |  |       var mode = canv.getMode(); | 
 |  |  |       if(mode !== mode_id) return; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var zoom = canv.getZoom(); | 
 |  |  |       var evt = opts.event | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var x = opts.mouse_x/zoom; | 
 |  |  |       var y = opts.mouse_y/zoom; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       var tlist = canv.getTransformList(cur_shape), | 
 |  |  |         box = cur_shape.getBBox(),  | 
 |  |  |         box = cur_shape.getBBox(), | 
 |  |  |         left = box.x, top = box.y, width = box.width, | 
 |  |  |         height = box.height; | 
 |  |  |       var dx = (x-start_x), dy = (y-start_y); | 
 |  |  | 
 |  |  |  | 
 |  |  |       var ts = null, | 
 |  |  |         tx = 0, ty = 0, | 
 |  |  |         sy = height ? (height+dy)/height : 1,  | 
 |  |  |         sy = height ? (height+dy)/height : 1, | 
 |  |  |         sx = width ? (width+dx)/width : 1; | 
 |  |  |  | 
 |  |  |       var sx = newbox.width / lastBBox.width; | 
 |  |  |       var sy = newbox.height / lastBBox.height; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       sx = sx || 1; | 
 |  |  |       sy = sy || 1; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // Not perfect, but mostly works... | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(x < start_x) { | 
 |  |  |         tx = lastBBox.width; | 
 |  |  |       } | 
 |  |  |       if(y < start_y) ty = lastBBox.height; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       // update the transform list with translate,scale,translate | 
 |  |  |       var translateOrigin = svgroot.createSVGTransform(), | 
 |  |  |         scale = svgroot.createSVGTransform(), | 
 |  |  |         translateBack = svgroot.createSVGTransform(); | 
 |  |  |          | 
 |  |  |  | 
 |  |  |       translateOrigin.setTranslate(-(left+tx), -(top+ty)); | 
 |  |  |       if(evt.shiftKey) { | 
 |  |  |         replaced = true | 
 |  |  | 
 |  |  |     mouseUp: function(opts) { | 
 |  |  |       var mode = canv.getMode(); | 
 |  |  |       if(mode !== mode_id) return; | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       if(opts.mouse_x == start_x && opts.mouse_y == start_y) { | 
 |  |  |         return { | 
 |  |  |           keep: false, | 
 |  |  | 
 |  |  |         element: cur_shape, | 
 |  |  |         started: false | 
 |  |  |       } | 
 |  |  |     }    | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | }); |