|
| 1 | +/* |
| 2 | + * Released under BSD License |
| 3 | + * Copyright (c) 2014-2015 hizzgdev@163.com |
| 4 | + * |
| 5 | + * Project Home: |
| 6 | + * https://github.com/hizzgdev/jsmind/ |
| 7 | + */ |
| 8 | + |
| 9 | +(function($w){ |
| 10 | + 'use strict'; |
| 11 | + |
| 12 | + var __name__ = 'jsMind'; |
| 13 | + var jsMind = $w[__name__]; |
| 14 | + if(!jsMind){return;} |
| 15 | + if(typeof jsMind.screenshot != 'undefined'){return;} |
| 16 | + |
| 17 | + var $d = $w.document; |
| 18 | + var $c = function(tag){return $d.createElement(tag);}; |
| 19 | + |
| 20 | + var css = function(cstyle,property_name){ |
| 21 | + return cstyle.getPropertyValue(property_name); |
| 22 | + }; |
| 23 | + var is_visible = function(cstyle){ |
| 24 | + var visibility = css(cstyle,'visibility'); |
| 25 | + var display = css(cstyle,'display'); |
| 26 | + return (visibility !== 'hidden' && display !== 'none'); |
| 27 | + }; |
| 28 | + var jcanvas = jsMind.util.canvas; |
| 29 | + jcanvas.rect = function (ctx,x,y,w,h,r) { |
| 30 | + if (w < 2 * r) r = w / 2; |
| 31 | + if (h < 2 * r) r = h / 2; |
| 32 | + ctx.moveTo(x+r, y); |
| 33 | + ctx.arcTo(x+w, y, x+w, y+h, r); |
| 34 | + ctx.arcTo(x+w, y+h, x, y+h, r); |
| 35 | + ctx.arcTo(x, y+h, x, y, r); |
| 36 | + ctx.arcTo(x, y, x+w, y, r); |
| 37 | + }; |
| 38 | + |
| 39 | + jcanvas.text_multiline = function(ctx,text,x,y,w,h,lineheight){ |
| 40 | + var line = ''; |
| 41 | + var text_len = text.length; |
| 42 | + var chars = text.split(''); |
| 43 | + var test_line = null; |
| 44 | + ctx.textAlign = 'left'; |
| 45 | + ctx.textBaseline = 'top'; |
| 46 | + for(var i=0;i<text_len;i++){ |
| 47 | + test_line = line + chars[i]; |
| 48 | + if(ctx.measureText(test_line).width > w && i>0){ |
| 49 | + ctx.fillText(line,x,y); |
| 50 | + line = chars[i]; |
| 51 | + y += lineheight; |
| 52 | + }else{ |
| 53 | + line = test_line; |
| 54 | + } |
| 55 | + } |
| 56 | + ctx.fillText(line,x,y); |
| 57 | + }; |
| 58 | + |
| 59 | + jcanvas.text_ellipsis = function(ctx,text,x,y,w,h){ |
| 60 | + var center_y = y+h/2; |
| 61 | + var text = jcanvas.fittingString(ctx,text,w); |
| 62 | + ctx.textAlign = 'left'; |
| 63 | + ctx.textBaseline = 'middle'; |
| 64 | + ctx.fillText(text,x,center_y,w); |
| 65 | + }; |
| 66 | + |
| 67 | + jcanvas.fittingString = function(ctx,text,max_width) { |
| 68 | + var width = ctx.measureText(text).width; |
| 69 | + var ellipsis = '…' |
| 70 | + var ellipsis_width = ctx.measureText(ellipsis).width; |
| 71 | + if (width<=max_width || width<=ellipsis_width) { |
| 72 | + return text; |
| 73 | + } else { |
| 74 | + var len = text.length; |
| 75 | + while (width>=max_width-ellipsis_width && len-->0) { |
| 76 | + text = text.substring(0, len); |
| 77 | + width = ctx.measureText(text).width; |
| 78 | + } |
| 79 | + return text+ellipsis; |
| 80 | + } |
| 81 | + }; |
| 82 | + |
| 83 | + jsMind.screenshot = function(jm){ |
| 84 | + this.jm = jm; |
| 85 | + this.canvas_elem = null; |
| 86 | + this.canvas_ctx = null; |
| 87 | + this._inited = false; |
| 88 | + }; |
| 89 | + |
| 90 | + jsMind.screenshot.prototype = { |
| 91 | + init:function(){ |
| 92 | + if(this._inited){return;} |
| 93 | + console.log('init'); |
| 94 | + var c = $c('canvas'); |
| 95 | + var ctx = c.getContext('2d'); |
| 96 | + |
| 97 | + this.canvas_elem = c; |
| 98 | + this.canvas_ctx = ctx; |
| 99 | + this.jm.view.e_panel.appendChild(c); |
| 100 | + this._inited = true; |
| 101 | + this.resize(); |
| 102 | + }, |
| 103 | + |
| 104 | + shoot:function(){ |
| 105 | + this.init(); |
| 106 | + this._draw(); |
| 107 | + this._watermark(); |
| 108 | + this._download(); |
| 109 | + this.clean(); |
| 110 | + }, |
| 111 | + |
| 112 | + shootAsDataURL:function(){ |
| 113 | + this.init(); |
| 114 | + this._draw(); |
| 115 | + this._watermark(); |
| 116 | + var url = this.canvas_elem.toDataURL(); |
| 117 | + this.clean(); |
| 118 | + return url; |
| 119 | + }, |
| 120 | + |
| 121 | + resize:function(){ |
| 122 | + if(this._inited){ |
| 123 | + this.canvas_elem.width=this.jm.view.size.w; |
| 124 | + this.canvas_elem.height=this.jm.view.size.h; |
| 125 | + } |
| 126 | + }, |
| 127 | + |
| 128 | + clean:function(){ |
| 129 | + var c = this.canvas_elem; |
| 130 | + this.canvas_ctx.clearRect(0,0,c.width,c.height); |
| 131 | + }, |
| 132 | + |
| 133 | + _draw:function(){ |
| 134 | + var ctx = this.canvas_ctx; |
| 135 | + ctx.textAlign = 'left'; |
| 136 | + ctx.textBaseline = 'top'; |
| 137 | + this._draw_lines(); |
| 138 | + this._draw_nodes(); |
| 139 | + }, |
| 140 | + |
| 141 | + _watermark:function(){ |
| 142 | + var c = this.canvas_elem; |
| 143 | + var ctx = this.canvas_ctx; |
| 144 | + ctx.textAlign='right'; |
| 145 | + ctx.textBaseline='bottom'; |
| 146 | + ctx.fillStyle='#000'; |
| 147 | + ctx.font='11px Verdana,Arial,Helvetica,sans-serif'; |
| 148 | + ctx.fillText('hizzgdev.github.io/jsmind',c.width-5.5,c.height-2.5); |
| 149 | + ctx.textAlign='left'; |
| 150 | + ctx.fillText($w.location,5.5,c.height-2.5); |
| 151 | + }, |
| 152 | + |
| 153 | + _draw_lines:function(){ |
| 154 | + this.jm.view.show_lines(this.canvas_ctx); |
| 155 | + }, |
| 156 | + |
| 157 | + _draw_nodes:function(){ |
| 158 | + var nodes = this.jm.mind.nodes; |
| 159 | + var node; |
| 160 | + for(var nodeid in nodes){ |
| 161 | + node = nodes[nodeid]; |
| 162 | + this._draw_node(node); |
| 163 | + } |
| 164 | + }, |
| 165 | + |
| 166 | + _draw_node:function(node){ |
| 167 | + var ctx = this.canvas_ctx; |
| 168 | + var view_data = node._data.view; |
| 169 | + var node_element = view_data.element; |
| 170 | + var ncs = getComputedStyle(node_element); |
| 171 | + if(!is_visible(ncs)){ return; } |
| 172 | + |
| 173 | + var bgcolor = css(ncs,'background-color'); |
| 174 | + var round_radius = parseInt(css(ncs,'border-radius')); |
| 175 | + var color = css(ncs,'color'); |
| 176 | + var font = css(ncs,'font'); |
| 177 | + var padding_left = parseInt(css(ncs,'padding-left')); |
| 178 | + var padding_right = parseInt(css(ncs,'padding-right')); |
| 179 | + var padding_top = parseInt(css(ncs,'padding-top')); |
| 180 | + var padding_bottom = parseInt(css(ncs,'padding-bottom')); |
| 181 | + var text_overflow = css(ncs,'text-overflow'); |
| 182 | + |
| 183 | + var rb = {x:view_data.abs_x, |
| 184 | + y:view_data.abs_y, |
| 185 | + w:view_data.width+1, |
| 186 | + h:view_data.height+1}; |
| 187 | + var tb = {x:rb.x+padding_left, |
| 188 | + y:rb.y+padding_top, |
| 189 | + w:rb.w-padding_left-padding_right, |
| 190 | + h:rb.h-padding_top-padding_bottom}; |
| 191 | + |
| 192 | + ctx.font=font; |
| 193 | + ctx.fillStyle = bgcolor; |
| 194 | + ctx.beginPath(); |
| 195 | + jcanvas.rect(ctx, rb.x, rb.y, rb.w, rb.h, round_radius); |
| 196 | + ctx.closePath(); |
| 197 | + ctx.fill(); |
| 198 | + |
| 199 | + ctx.fillStyle = color; |
| 200 | + if(text_overflow === 'ellipsis'){ |
| 201 | + jcanvas.text_ellipsis(ctx, node.topic, tb.x, tb.y, tb.w, tb.h); |
| 202 | + }else{ |
| 203 | + var line_height = parseInt(css(ncs,'line-height')); |
| 204 | + jcanvas.text_multiline(ctx, node.topic, tb.x, tb.y, tb.w, tb.h,line_height); |
| 205 | + } |
| 206 | + |
| 207 | + if(!!view_data.expander){ |
| 208 | + this._draw_expander(view_data.expander); |
| 209 | + } |
| 210 | + }, |
| 211 | + |
| 212 | + _draw_expander:function(expander){ |
| 213 | + var ctx = this.canvas_ctx; |
| 214 | + var ncs = getComputedStyle(expander); |
| 215 | + if(!is_visible(ncs)){ return; } |
| 216 | + |
| 217 | + var style_left = css(ncs,'left'); |
| 218 | + var style_top = css(ncs,'top'); |
| 219 | + var font = css(ncs,'font'); |
| 220 | + var left = parseInt(style_left); |
| 221 | + var top = parseInt(style_top); |
| 222 | + var is_plus = expander.innerHTML === '+'; |
| 223 | + |
| 224 | + ctx.lineWidth = 1; |
| 225 | + |
| 226 | + ctx.beginPath(); |
| 227 | + ctx.arc(left+7,top+7,5,0,Math.PI*2,true); |
| 228 | + ctx.moveTo(left+10,top+7); |
| 229 | + ctx.lineTo(left+4,top+7); |
| 230 | + if(is_plus){ |
| 231 | + ctx.moveTo(left+7,top+4); |
| 232 | + ctx.lineTo(left+7,top+10); |
| 233 | + } |
| 234 | + ctx.closePath(); |
| 235 | + ctx.stroke(); |
| 236 | + }, |
| 237 | + |
| 238 | + _download:function(){ |
| 239 | + var c = this.canvas_elem; |
| 240 | + var name = this.jm.mind.name; |
| 241 | + |
| 242 | + if (navigator.msSaveBlob && (!!c.msToBlob)) { |
| 243 | + var blob = c.msToBlob(); |
| 244 | + navigator.msSaveBlob(blob,name); |
| 245 | + } else { |
| 246 | + var bloburl = this.canvas_elem.toDataURL(); |
| 247 | + var anchor = $c('a'); |
| 248 | + if ('download' in anchor) { |
| 249 | + anchor.style.visibility = 'hidden'; |
| 250 | + anchor.href = bloburl; |
| 251 | + anchor.download = this.jm.mind.name; |
| 252 | + $d.body.appendChild(anchor); |
| 253 | + var evt = $d.createEvent('MouseEvents'); |
| 254 | + evt.initEvent('click', true, true); |
| 255 | + anchor.dispatchEvent(evt); |
| 256 | + $d.body.removeChild(anchor); |
| 257 | + } else { |
| 258 | + location.href = bloburl; |
| 259 | + } |
| 260 | + } |
| 261 | + }, |
| 262 | + |
| 263 | + jm_event_handle:function(type,data){ |
| 264 | + if(type === jsMind.event_type.resize){ |
| 265 | + this.resize(); |
| 266 | + } |
| 267 | + } |
| 268 | + }; |
| 269 | + |
| 270 | + var screenshot_plugin = new jsMind.plugin('screenshot',function(jm){ |
| 271 | + var jss = new jsMind.screenshot(jm); |
| 272 | + jm.screenshot = jss; |
| 273 | + jm.shoot = function(){ |
| 274 | + jss.shoot(); |
| 275 | + }; |
| 276 | + jm.add_event_listener(function(type,data){ |
| 277 | + jss.jm_event_handle.call(jss,type,data); |
| 278 | + }); |
| 279 | + }); |
| 280 | + |
| 281 | + jsMind.register_plugin(screenshot_plugin); |
| 282 | + |
| 283 | +})(window); |
0 commit comments