Skip to content

Commit 471ab24

Browse files
committed
Merge pull request hizzgdev#22 from ttsdzzg/dev/screenshot_plugin
Dev/screenshot plugin , resolve hizzgdev#9
2 parents 1a5a28b + 7325fa8 commit 471ab24

4 files changed

Lines changed: 314 additions & 22 deletions

File tree

‎example/1_basic.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
// var mind_data = jm.get_data();
5454
// alert(mind_data);
5555
}
56-
56+
5757
load_jsmind();
5858
</script>
5959
</body>

‎example/2_features.html‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<li><button onclick="open_ajax();">open remote</button></li>
3333
<li><button onclick="prompt_info('see 6.Multi Format');">open local file</button></li>
3434
<li><button onclick="prompt_info('see 6.Multi Format');">save local file</button></li>
35+
<li><button onclick="screen_shot();">screenshot</button></li>
3536
</ol>
3637
</ol>
3738
<div>2. Select &amp; Toggle</div>
@@ -109,6 +110,7 @@
109110
</div>
110111
<script type="text/javascript" src="../js/jsmind.js"></script>
111112
<script type="text/javascript" src="../js/jsmind.draggable.js"></script>
113+
<script type="text/javascript" src="../js/jsmind.screenshot.js"></script>
112114
<script type="text/javascript">
113115
var _jm = null;
114116
function open_empty(){
@@ -161,6 +163,10 @@
161163
});
162164
}
163165

166+
function screen_shot(){
167+
_jm.shoot();
168+
}
169+
164170
function show_data(){
165171
var mind_data = _jm.get_data();
166172
var mind_string = jsMind.util.json.json2string(mind_data);

‎js/jsmind.js‎

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -944,22 +944,24 @@
944944
bb.append(file_data);
945945
blob = bb.getBlob(type);
946946
}
947-
var URL = $w.URL || $w.webkitURL;
948-
var bloburl = URL.createObjectURL(blob);
949-
var anchor = $c('a');
950-
if ('download' in anchor) {
951-
anchor.style.visibility = 'hidden';
952-
anchor.href = bloburl;
953-
anchor.download = name;
954-
$d.body.appendChild(anchor);
955-
var evt = $d.createEvent('MouseEvents');
956-
evt.initEvent('click', true, true);
957-
anchor.dispatchEvent(evt);
958-
$d.body.removeChild(anchor);
959-
} else if (navigator.msSaveBlob) {
947+
if (navigator.msSaveBlob) {
960948
navigator.msSaveBlob(blob, name);
961949
} else {
962-
location.href = bloburl;
950+
var URL = $w.URL || $w.webkitURL;
951+
var bloburl = URL.createObjectURL(blob);
952+
var anchor = $c('a');
953+
if ('download' in anchor) {
954+
anchor.style.visibility = 'hidden';
955+
anchor.href = bloburl;
956+
anchor.download = name;
957+
$d.body.appendChild(anchor);
958+
var evt = $d.createEvent('MouseEvents');
959+
evt.initEvent('click', true, true);
960+
anchor.dispatchEvent(evt);
961+
$d.body.removeChild(anchor);
962+
} else {
963+
location.href = bloburl;
964+
}
963965
}
964966
}
965967
},
@@ -2272,12 +2274,13 @@
22722274
}
22732275
},
22742276

2275-
clear_lines:function(){
2276-
jm.util.canvas.clear(this.canvas_ctx,0,0,this.size.w,this.size.h);
2277+
clear_lines:function(canvas_ctx){
2278+
var ctx = canvas_ctx || this.canvas_ctx;
2279+
jm.util.canvas.clear(ctx,0,0,this.size.w,this.size.h);
22772280
},
22782281

2279-
show_lines:function(){
2280-
this.clear_lines();
2282+
show_lines:function(canvas_ctx){
2283+
this.clear_lines(canvas_ctx);
22812284
var nodes = this.jm.mind.nodes;
22822285
var node = null;
22832286
var pin = null;
@@ -2289,12 +2292,12 @@
22892292
if(('visible' in node._data.layout) && !node._data.layout.visible){continue;}
22902293
pin = this.layout.get_node_point_in(node);
22912294
pout = this.layout.get_node_point_out(node.parent);
2292-
this.draw_line(pout,pin,_offset);
2295+
this.draw_line(pout,pin,_offset,canvas_ctx);
22932296
}
22942297
},
22952298

2296-
draw_line:function(pin,pout,offset){
2297-
var ctx = this.canvas_ctx;
2299+
draw_line:function(pin,pout,offset,canvas_ctx){
2300+
var ctx = canvas_ctx || this.canvas_ctx;
22982301
ctx.strokeStyle = this.opts.line_color;
22992302
ctx.lineWidth = this.opts.line_width;
23002303
ctx.lineCap = 'round';

‎js/jsmind.screenshot.js‎

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
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

Comments
 (0)