|  |  | 
 |  |  |  */ | 
 |  |  |  | 
 |  |  | 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', | 
 |  |  |     object: 'Objects', | 
 |  |  |     symbol: 'Symbols', | 
 |  |  |     arrow: 'Arrows', | 
 |  |  |     flowchart: 'Flowchart', | 
 |  |  |     nature: 'Nature', | 
 |  |  |     game: 'Cards & Chess', | 
 |  |  |     dialog_balloon: 'Dialog balloons', | 
 |  |  |     music: 'Music', | 
 |  |  |     weather: 'Weather & Time', | 
 |  |  |     ui: 'User Interface', | 
 |  |  |     social: 'Social Web' | 
 |  |  |     basic: '基本', | 
 |  |  |     object: '物体', | 
 |  |  |     symbol: '符号', | 
 |  |  |     arrow: '箭头', | 
 |  |  |     flowchart: '流程图', | 
 |  |  |     nature: '自然', | 
 |  |  |     game: '纸牌与象棋', | 
 |  |  |     dialog_balloon: '对话框', | 
 |  |  |     music: '音乐', | 
 |  |  |     weather: '天气与时间', | 
 |  |  |     ui: '用户接口', | 
 |  |  |     social: '社交网络' | 
 |  |  |   }; | 
 |  |  |    | 
 |  |  |  | 
 |  |  |   var library = { | 
 |  |  |     'basic': { | 
 |  |  |       data: { | 
 |  |  | 
 |  |  |         "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>'; | 
 |  |  |       }); | 
 |  |  |        | 
 |  |  |  | 
 |  |  |       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 | 
 |  |  |       } | 
 |  |  |     }    | 
 |  |  |     } | 
 |  |  |   } | 
 |  |  | }); |