| 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);
 |