123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- /*
- * Released under BSD License
- * Copyright (c) 2014-2021 hizzgdev@163.com
- *
- * Project Home:
- * https://github.com/hizzgdev/jsmind/
- */
- (function ($w) {
- 'use strict';
- var __name__ = 'jsMind';
- var jsMind = $w[__name__];
- if (!jsMind) { return; }
- if (typeof jsMind.screenshot != 'undefined') { return; }
- var $d = $w.document;
- var $c = function (tag) { return $d.createElement(tag); };
- var css = function (cstyle, property_name) {
- return cstyle.getPropertyValue(property_name);
- };
- var is_visible = function (cstyle) {
- var visibility = css(cstyle, 'visibility');
- var display = css(cstyle, 'display');
- return (visibility !== 'hidden' && display !== 'none');
- };
- var jcanvas = {};
- jcanvas.rect = function (ctx, x, y, w, h, r) {
- if (w < 2 * r) r = w / 2;
- if (h < 2 * r) r = h / 2;
- ctx.moveTo(x + r, y);
- ctx.arcTo(x + w, y, x + w, y + h, r);
- ctx.arcTo(x + w, y + h, x, y + h, r);
- ctx.arcTo(x, y + h, x, y, r);
- ctx.arcTo(x, y, x + w, y, r);
- };
- jcanvas.text_multiline = function (ctx, text, x, y, w, h, lineheight) {
- var line = '';
- var text_len = text.length;
- var chars = text.split('');
- var test_line = null;
- ctx.textAlign = 'left';
- ctx.textBaseline = 'top';
- for (var i = 0; i < text_len; i++) {
- test_line = line + chars[i];
- if (ctx.measureText(test_line).width > w && i > 0) {
- ctx.fillText(line, x, y);
- line = chars[i];
- y += lineheight;
- } else {
- line = test_line;
- }
- }
- ctx.fillText(line, x, y);
- };
- jcanvas.text_ellipsis = function (ctx, text, x, y, w, h) {
- var center_y = y + h / 2;
- var text = jcanvas.fittingString(ctx, text, w);
- ctx.textAlign = 'left';
- ctx.textBaseline = 'middle';
- ctx.fillText(text, x, center_y, w);
- };
- jcanvas.fittingString = function (ctx, text, max_width) {
- var width = ctx.measureText(text).width;
- var ellipsis = '…';
- var ellipsis_width = ctx.measureText(ellipsis).width;
- if (width <= max_width || width <= ellipsis_width) {
- return text;
- } else {
- var len = text.length;
- while (width >= max_width - ellipsis_width && len-- > 0) {
- text = text.substring(0, len);
- width = ctx.measureText(text).width;
- }
- return text + ellipsis;
- }
- };
- jcanvas.image = function (ctx, url, x, y, w, h, r, rotation, callback) {
- var img = new Image();
- img.onload = function () {
- ctx.save();
- ctx.translate(x, y);
- ctx.save();
- ctx.beginPath();
- jcanvas.rect(ctx, 0, 0, w, h, r);
- ctx.closePath();
- ctx.clip();
- ctx.translate(w / 2, h / 2);
- ctx.rotate(rotation * Math.PI / 180);
- ctx.drawImage(img, -w / 2, -h / 2);
- ctx.restore();
- ctx.restore();
- !!callback && callback();
- }
- img.src = url;
- };
- jsMind.screenshot = function (jm) {
- this.jm = jm;
- this.canvas_elem = null;
- this.canvas_ctx = null;
- this._inited = false;
- };
- jsMind.screenshot.prototype = {
- init: function () {
- if (this._inited) { return; }
- console.log('init');
- var c = $c('canvas');
- var ctx = c.getContext('2d');
- this.canvas_elem = c;
- this.canvas_ctx = ctx;
- this.jm.view.e_panel.appendChild(c);
- this._inited = true;
- this.resize();
- },
- shoot: function (callback) {
- this.init();
- this._draw(function () {
- !!callback && callback();
- this.clean();
- }.bind(this));
- this._watermark();
- },
- shootDownload: function () {
- this.shoot(function () {
- this._download();
- }.bind(this));
- },
- shootAsDataURL: function (callback) {
- this.shoot(function () {
- !!callback && callback(this.canvas_elem.toDataURL());
- }.bind(this));
- },
- resize: function () {
- if (this._inited) {
- this.canvas_elem.width = this.jm.view.size.w;
- this.canvas_elem.height = this.jm.view.size.h;
- }
- },
- clean: function () {
- var c = this.canvas_elem;
- this.canvas_ctx.clearRect(0, 0, c.width, c.height);
- },
- _draw: function (callback) {
- var ctx = this.canvas_ctx;
- ctx.textAlign = 'left';
- ctx.textBaseline = 'top';
- this._draw_lines(function () {
- this._draw_nodes(callback);
- }.bind(this));
- },
- _watermark: function () {
- var c = this.canvas_elem;
- var ctx = this.canvas_ctx;
- ctx.textAlign = 'right';
- ctx.textBaseline = 'bottom';
- ctx.fillStyle = '#000';
- ctx.font = '11px Verdana,Arial,Helvetica,sans-serif';
- ctx.fillText('hizzgdev.github.io/jsmind', c.width - 5.5, c.height - 2.5);
- ctx.textAlign = 'left';
- ctx.fillText($w.location, 5.5, c.height - 2.5);
- },
- _draw_lines: function (callback) {
- this.jm.view.graph.copy_to(this.canvas_ctx, callback);
- },
- _draw_nodes: function (callback) {
- var nodes = this.jm.mind.nodes;
- var node;
- for (var nodeid in nodes) {
- node = nodes[nodeid];
- this._draw_node(node);
- }
- function check_nodes_ready() {
- console.log('check_node_ready' + new Date());
- var allOk = true;
- for (var nodeid in nodes) {
- node = nodes[nodeid];
- allOk = allOk & node.ready;
- }
- if (!allOk) {
- $w.setTimeout(check_nodes_ready, 200);
- } else {
- $w.setTimeout(callback, 200);
- }
- }
- check_nodes_ready();
- },
- _draw_node: function (node) {
- var ctx = this.canvas_ctx;
- var view_data = node._data.view;
- var node_element = view_data.element;
- var ncs = getComputedStyle(node_element);
- if (!is_visible(ncs)) {
- node.ready = true;
- return;
- }
- var bgcolor = css(ncs, 'background-color');
- var round_radius = parseInt(css(ncs, 'border-top-left-radius'));
- var color = css(ncs, 'color');
- var padding_left = parseInt(css(ncs, 'padding-left'));
- var padding_right = parseInt(css(ncs, 'padding-right'));
- var padding_top = parseInt(css(ncs, 'padding-top'));
- var padding_bottom = parseInt(css(ncs, 'padding-bottom'));
- var text_overflow = css(ncs, 'text-overflow');
- var font = css(ncs, 'font-style') + ' ' +
- css(ncs, 'font-variant') + ' ' +
- css(ncs, 'font-weight') + ' ' +
- css(ncs, 'font-size') + '/' + css(ncs, 'line-height') + ' ' +
- css(ncs, 'font-family');
- var rb = {
- x: view_data.abs_x,
- y: view_data.abs_y,
- w: view_data.width + 1,
- h: view_data.height + 1
- };
- var tb = {
- x: rb.x + padding_left,
- y: rb.y + padding_top,
- w: rb.w - padding_left - padding_right,
- h: rb.h - padding_top - padding_bottom
- };
- ctx.font = font;
- ctx.fillStyle = bgcolor;
- ctx.beginPath();
- jcanvas.rect(ctx, rb.x, rb.y, rb.w, rb.h, round_radius);
- ctx.closePath();
- ctx.fill();
- ctx.fillStyle = color;
- if ('background-image' in node.data) {
- var backgroundUrl = css(ncs, 'background-image').slice(5, -2);
- node.ready = false;
- var rotation = 0;
- if ('background-rotation' in node.data) {
- rotation = node.data['background-rotation'];
- }
- jcanvas.image(ctx, backgroundUrl, rb.x, rb.y, rb.w, rb.h, round_radius, rotation,
- function () {
- node.ready = true;
- });
- }
- if (!!node.topic) {
- if (text_overflow === 'ellipsis') {
- jcanvas.text_ellipsis(ctx, node.topic, tb.x, tb.y, tb.w, tb.h);
- } else {
- var line_height = parseInt(css(ncs, 'line-height'));
- jcanvas.text_multiline(ctx, node.topic, tb.x, tb.y, tb.w, tb.h, line_height);
- }
- }
- if (!!view_data.expander) {
- this._draw_expander(view_data.expander);
- }
- if (!('background-image' in node.data)) {
- node.ready = true;
- }
- },
- _draw_expander: function (expander) {
- var ctx = this.canvas_ctx;
- var ncs = getComputedStyle(expander);
- if (!is_visible(ncs)) { return; }
- var style_left = css(ncs, 'left');
- var style_top = css(ncs, 'top');
- var font = css(ncs, 'font');
- var left = parseInt(style_left);
- var top = parseInt(style_top);
- var is_plus = expander.innerHTML === '+';
- ctx.lineWidth = 1;
- ctx.beginPath();
- ctx.arc(left + 7, top + 7, 5, 0, Math.PI * 2, true);
- ctx.moveTo(left + 10, top + 7);
- ctx.lineTo(left + 4, top + 7);
- if (is_plus) {
- ctx.moveTo(left + 7, top + 4);
- ctx.lineTo(left + 7, top + 10);
- }
- ctx.closePath();
- ctx.stroke();
- },
- _download: function () {
- var c = this.canvas_elem;
- var name = this.jm.mind.name + '.png';
- if (navigator.msSaveBlob && (!!c.msToBlob)) {
- var blob = c.msToBlob();
- navigator.msSaveBlob(blob, name);
- } else {
- var bloburl = this.canvas_elem.toDataURL();
- var anchor = $c('a');
- if ('download' in anchor) {
- anchor.style.visibility = 'hidden';
- anchor.href = bloburl;
- anchor.download = name;
- $d.body.appendChild(anchor);
- var evt = $d.createEvent('MouseEvents');
- evt.initEvent('click', true, true);
- anchor.dispatchEvent(evt);
- $d.body.removeChild(anchor);
- } else {
- location.href = bloburl;
- }
- }
- },
- jm_event_handle: function (type, data) {
- if (type === jsMind.event_type.resize) {
- this.resize();
- }
- }
- };
- var screenshot_plugin = new jsMind.plugin('screenshot', function (jm) {
- var jss = new jsMind.screenshot(jm);
- jm.screenshot = jss;
- jm.shoot = function () {
- jss.shoot();
- };
- jm.add_event_listener(function (type, data) {
- jss.jm_event_handle.call(jss, type, data);
- });
- });
- jsMind.register_plugin(screenshot_plugin);
- })(window);
|