159 lines
4.4 KiB
JavaScript
Executable File
159 lines
4.4 KiB
JavaScript
Executable File
import jsMind from 'jsmind'
|
|
import domtoimage from 'dom-to-image'
|
|
|
|
if (!jsMind) {
|
|
throw new Error('jsMind is not defined')
|
|
}
|
|
|
|
if (!domtoimage) {
|
|
throw new Error('dom-to-image is required')
|
|
}
|
|
|
|
const $ = jsMind.$
|
|
|
|
const DEFAULT_OPTIONS = {
|
|
filename: null,
|
|
watermark: {
|
|
left: $.w.location,
|
|
right: 'https://github.com/hizzgdev/jsmind',
|
|
},
|
|
background: 'transparent',
|
|
}
|
|
|
|
class JmScreenshot {
|
|
constructor(jm, options) {
|
|
var opts = {}
|
|
jsMind.util.json.merge(opts, DEFAULT_OPTIONS)
|
|
jsMind.util.json.merge(opts, options)
|
|
|
|
this.version = '0.2.0'
|
|
this.jm = jm
|
|
this.options = opts
|
|
this.dpr = jm.view.device_pixel_ratio
|
|
}
|
|
|
|
shoot() {
|
|
let c = this.create_canvas()
|
|
let ctx = c.getContext('2d')
|
|
ctx.scale(this.dpr, this.dpr)
|
|
Promise.resolve(ctx)
|
|
.then(() => this.draw_background(ctx))
|
|
.then(() => this.draw_lines(ctx))
|
|
.then(() => this.draw_nodes(ctx))
|
|
.then(() => this.draw_watermark(c, ctx))
|
|
.then(() => this.download(c))
|
|
.then(() => this.clear(c))
|
|
}
|
|
|
|
create_canvas() {
|
|
let c = $.c('canvas')
|
|
const w = this.jm.view.size.w
|
|
const h = this.jm.view.size.h
|
|
c.width = w * this.dpr
|
|
c.height = h * this.dpr
|
|
c.style.width = w + 'px'
|
|
c.style.height = h + 'px'
|
|
|
|
c.style.visibility = 'hidden'
|
|
this.jm.view.e_panel.appendChild(c)
|
|
return c
|
|
}
|
|
|
|
clear(c) {
|
|
c.parentNode.removeChild(c)
|
|
}
|
|
|
|
draw_background(ctx) {
|
|
return new Promise(
|
|
function (resolve, _) {
|
|
const bg = this.options.background
|
|
if (!!bg && bg !== 'transparent') {
|
|
ctx.fillStyle = this.options.background
|
|
ctx.fillRect(0, 0, this.jm.view.size.w, this.jm.view.size.h)
|
|
}
|
|
resolve(ctx)
|
|
}.bind(this)
|
|
)
|
|
}
|
|
|
|
draw_lines(ctx) {
|
|
return new Promise(
|
|
function (resolve, _) {
|
|
this.jm.view.graph.copy_to(ctx, function () {
|
|
resolve(ctx)
|
|
})
|
|
}.bind(this)
|
|
)
|
|
}
|
|
|
|
draw_nodes(ctx) {
|
|
return domtoimage
|
|
.toSvg(this.jm.view.e_nodes, { style: { zoom: 1 } })
|
|
.then(this.load_image)
|
|
.then(function (img) {
|
|
ctx.drawImage(img, 0, 0)
|
|
return ctx
|
|
})
|
|
}
|
|
|
|
draw_watermark(c, ctx) {
|
|
ctx.textBaseline = 'bottom'
|
|
ctx.fillStyle = '#000'
|
|
ctx.font = '11px Verdana,Arial,Helvetica,sans-serif'
|
|
if (!!this.options.watermark.left) {
|
|
ctx.textAlign = 'left'
|
|
ctx.fillText(this.options.watermark.left, 5.5, c.height - 2.5)
|
|
}
|
|
if (!!this.options.watermark.right) {
|
|
ctx.textAlign = 'right'
|
|
ctx.fillText(this.options.watermark.right, c.width - 5.5, c.height - 2.5)
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
load_image(url) {
|
|
return new Promise(function (resolve, reject) {
|
|
let img = new Image()
|
|
img.onload = function () {
|
|
resolve(img)
|
|
}
|
|
img.onerror = reject
|
|
img.src = url
|
|
})
|
|
}
|
|
|
|
download(c) {
|
|
var name = (this.options.filename || this.jm.mind.name) + '.png'
|
|
|
|
if (navigator.msSaveBlob && !!c.msToBlob) {
|
|
var blob = c.msToBlob()
|
|
navigator.msSaveBlob(blob, name)
|
|
} else {
|
|
var blob_url = c.toDataURL()
|
|
var anchor = $.c('a')
|
|
if ('download' in anchor) {
|
|
anchor.style.visibility = 'hidden'
|
|
anchor.href = blob_url
|
|
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 = blob_url
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let screenshot_plugin = new jsMind.plugin('screenshot', function (jm, options) {
|
|
var jmss = new JmScreenshot(jm, options)
|
|
jm.screenshot = jmss
|
|
jm.shoot = function () {
|
|
jmss.shoot()
|
|
}
|
|
})
|
|
|
|
jsMind.register_plugin(screenshot_plugin)
|