Improved load/save

This commit is contained in:
neauoire 2019-11-03 20:44:31 -05:00
parent 7ceef4a5eb
commit 7a618f6925
12 changed files with 109 additions and 281 deletions

View File

@ -1,7 +1,9 @@
const { app, BrowserWindow, webFrame, Menu } = require('electron')
'use strict'
/* global createWindow */
const { app, BrowserWindow, Menu } = require('electron')
const path = require('path')
const url = require('url')
const shell = require('electron').shell
let isShown = true
@ -23,10 +25,9 @@ app.on('ready', () => {
})
app.win.loadURL(`file://${__dirname}/sources/index.html`)
// app.inspect()
app.inspect()
app.win.on('closed', () => {
win = null
app.quit()
})

View File

@ -20,7 +20,21 @@
"push": "npm run build ; npm run push_theme ; npm run push_osx ; npm run push_linux ; npm run push_win ; npm run clean ; npm run push_status"
},
"devDependencies": {
"electron": "^5.0.6",
"electron-packager": "^13.1.1"
"electron": "^7.0.0",
"electron-packager": "^14.0.6"
},
"standard": {
"globals": [
"localStorage",
"DOMParser",
"onMessage",
"postMessage",
"FileReader",
"performance",
"Worker"
],
"ignore": [
"/node_modules/*"
]
}
}

View File

@ -4,127 +4,53 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Twitter -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@neauoire">
<meta name="twitter:title" content="Dotgrid">
<meta name="twitter:description" content="A minimalist vector graphics tool.">
<meta name="twitter:creator" content="@neauoire">
<meta name="twitter:image" content="https://hundredrabbits.github.io/Dotgrid/media/services/meta.jpg">
<!-- Facebook -->
<meta property="og:title" content="Dotgrid" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://wiki.xxiivv.com/Dotgrid" />
<meta property="og:image" content="https://hundredrabbits.github.io/Dotgrid/media/services/meta.jpg" />
<meta property="og:description" content="A minimalist vector graphics tool." />
<meta property="og:site_name" content="Dotgrid" />
<!-- Generics -->
<script type="text/javascript" src="scripts/lib/acels.js"></script>
<script type="text/javascript" src="scripts/lib/theme.js"></script>
<script type="text/javascript" src="scripts/lib/history.js"></script>
<script type="text/javascript" src="scripts/lib/controller.js"></script>
<script type="text/javascript" src="scripts/lib/source.js"></script>
<!-- Dotgrid -->
<script type="text/javascript" src="scripts/dotgrid.js"></script>
<script type="text/javascript" src="scripts/manager.js"></script>
<script type="text/javascript" src="scripts/source.js"></script>
<script type="text/javascript" src="scripts/renderer.js"></script>
<script type="text/javascript" src="scripts/cursor.js"></script>
<script type="text/javascript" src="scripts/interface.js"></script>
<script type="text/javascript" src="scripts/tool.js"></script>
<script type="text/javascript" src="scripts/generator.js"></script>
<script type="text/javascript" src="scripts/picker.js"></script>
<script type="text/javascript" src="scripts/listener.js"></script>
<!-- Styles -->
<link rel="stylesheet" type="text/css" href="links/reset.css"/>
<link rel="stylesheet" type="text/css" href="links/fonts.css"/>
<link rel="stylesheet" type="text/css" href="links/main.css"/>
<link rel="stylesheet" type="text/css" href="links/theme.css"/>
<title>Dotgrid(Icon)</title>
<title>Dotgrid</title>
</head>
<body>
<body class='web'>
<script>
'use strict'
const webFrame = require('electron').webFrame
const {dialog,app} = require('electron').remote;
const fs = require('fs');
const dotgrid = new Dotgrid()
dotgrid.controller = new Controller();
'use strict'
dotgrid.controller.add("default","*","About",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Dotgrid'); },"CmdOrCtrl+,");
dotgrid.controller.add("default","*","Fullscreen",() => { app.toggleFullscreen(); },"CmdOrCtrl+Enter");
dotgrid.controller.add("default","*","Hide",() => { app.toggleVisible(); },"CmdOrCtrl+H");
dotgrid.controller.add("default","*","Inspect",() => { app.inspect(); },"CmdOrCtrl+.");
dotgrid.controller.add("default","*","Reset",() => { dotgrid.reset(); dotgrid.theme.reset(); },"CmdOrCtrl+Backspace");
dotgrid.controller.add("default","*","Quit",() => { app.exit(); },"CmdOrCtrl+Q");
const dotgrid = new Dotgrid()
dotgrid.controller.add("default","File","New",() => { dotgrid.source.new(); },"CmdOrCtrl+N");
dotgrid.controller.add("default","File","Open",() => { dotgrid.source.open(); },"CmdOrCtrl+O");
dotgrid.controller.add("default","File","Save(.grid)",() => { dotgrid.source.save(); },"CmdOrCtrl+S");
dotgrid.controller.add("default","File","Render(.png)",() => { dotgrid.source.render(); },"CmdOrCtrl+R");
dotgrid.controller.add("default","File","Export(.svg)",() => { dotgrid.source.export(); },"CmdOrCtrl+E");
dotgrid.install(document.body)
dotgrid.controller.addRole("default","Edit","copy");
dotgrid.controller.addRole("default","Edit","cut");
dotgrid.controller.addRole("default","Edit","paste");
dotgrid.controller.add("default","Edit","Undo",() => { dotgrid.tool.undo() },"CmdOrCtrl+Z");
dotgrid.controller.add("default","Edit","Redo",() => { dotgrid.tool.redo() },"CmdOrCtrl+Shift+Z");
dotgrid.controller.add("default","Stroke","Line",() => { dotgrid.tool.cast("line"); },"A");
dotgrid.controller.add("default","Stroke","Arc",() => { dotgrid.tool.cast("arc_c"); },"S"); // 0,1
dotgrid.controller.add("default","Stroke","Arc Rev",() => { dotgrid.tool.cast("arc_r")},"D"); // 0,0
dotgrid.controller.add("default","Stroke","Bezier",() => { dotgrid.tool.cast("bezier") },"F");
dotgrid.controller.add("default","Stroke","Close",() => { dotgrid.tool.cast("close") },"Z");
dotgrid.controller.add("default","Stroke","Arc(full)",() => { dotgrid.tool.cast("arc_c_full"); },"T"); // 1,1
dotgrid.controller.add("default","Stroke","Arc Rev(full)",() => { dotgrid.tool.cast("arc_r_full")},"Y"); // 1,0
dotgrid.controller.add("default","Stroke","Clear Selection",() => { dotgrid.tool.clear(); },"Escape");
dotgrid.controller.add("default","Effect","Linecap",() => { dotgrid.tool.toggle("linecap"); },"Q");
dotgrid.controller.add("default","Effect","Linejoin",() => { dotgrid.tool.toggle("linejoin"); },"W");
dotgrid.controller.add("default","Effect","Mirror",() => { dotgrid.tool.toggle("mirror"); },"E");
dotgrid.controller.add("default","Effect","Fill",() => { dotgrid.tool.toggle("fill"); },"R");
dotgrid.controller.add("default","Effect","Thicker",() => { dotgrid.tool.toggle("thickness",1) },"}");
dotgrid.controller.add("default","Effect","Thinner",() => { dotgrid.tool.toggle("thickness",-1) },"{");
dotgrid.controller.add("default","Effect","Thicker +5",() => { dotgrid.tool.toggle("thickness",5) },"]");
dotgrid.controller.add("default","Effect","Thinner -5",() => { dotgrid.tool.toggle("thickness",-5) },"[");
dotgrid.controller.add("default","Effect","Toggle Crest",() => { dotgrid.tool.toggleCrest(); }, "CmdOrCtrl+K");
dotgrid.controller.add("default","Manual","Add Point",() => { dotgrid.tool.addVertex(dotgrid.cursor.pos); dotgrid.renderer.update() },"Enter");
dotgrid.controller.add("default","Manual","Move Up",() => { dotgrid.cursor.pos.y -= 15; dotgrid.renderer.update() },"Up");
dotgrid.controller.add("default","Manual","Move Right",() => { dotgrid.cursor.pos.x += 15; dotgrid.renderer.update() },"Right");
dotgrid.controller.add("default","Manual","Move Down",() => { dotgrid.cursor.pos.y += 15; dotgrid.renderer.update() },"Down");
dotgrid.controller.add("default","Manual","Move Left",() => { dotgrid.cursor.pos.x -= 15; dotgrid.renderer.update() },"Left");
dotgrid.controller.add("default","Manual","Remove Point",() => { dotgrid.tool.removeSegmentsAt(dotgrid.cursor.pos); },"Shift+Backspace");
dotgrid.controller.add("default","Manual","Remove Segment",() => { dotgrid.tool.removeSegment(); },"Backspace");
dotgrid.controller.add("default","Layers","Foreground",() => { dotgrid.tool.selectLayer(0) },"CmdOrCtrl+1");
dotgrid.controller.add("default","Layers","Middleground",() => { dotgrid.tool.selectLayer(1) },"CmdOrCtrl+2");
dotgrid.controller.add("default","Layers","Background",() => { dotgrid.tool.selectLayer(2) },"CmdOrCtrl+3");
dotgrid.controller.add("default","Layers","Next Layer",() => { dotgrid.tool.selectNextLayer() });
dotgrid.controller.add("default","Layers","Prev Layer",() => { dotgrid.tool.selectPrevLayer() });
dotgrid.controller.add("default","Layers","Merge Layers",() => { dotgrid.tool.merge() },"M");
dotgrid.controller.add("default","View","Zoom In",() => { dotgrid.modZoom(0.25) },"CmdOrCtrl+=")
dotgrid.controller.add("default","View","Zoom Out",() => { dotgrid.modZoom(-0.25) },"CmdOrCtrl+-")
dotgrid.controller.add("default","View","Zoom Reset",() => { dotgrid.modZoom(1,true) },"CmdOrCtrl+0")
dotgrid.controller.add("default","View","Color Picker",() => { dotgrid.picker.start(); },"G");
dotgrid.controller.add("default","View","Toggle Grid",() => { dotgrid.renderer.toggle(); },"H");
dotgrid.controller.add("default","View","Toggle Interface",() => { dotgrid.interface.toggle(); },"Tab");
dotgrid.controller.add("default","Theme","Open Theme",() => { dotgrid.theme.open(); },"CmdOrCtrl+Shift+o")
dotgrid.controller.add("default","Theme","Reset Theme",() => { dotgrid.theme.reset(); },"CmdOrCtrl+Shift+Backspace")
dotgrid.controller.add("default","Theme","Download Themes..",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Themes'); })
dotgrid.controller.add("picker","*","About",() => { require('electron').shell.openExternal('https://github.com/hundredrabbits/Dotgrid'); },"CmdOrCtrl+,");
dotgrid.controller.add("picker","*","Fullscreen",() => { app.toggleFullscreen(); },"CmdOrCtrl+Enter");
dotgrid.controller.add("picker","*","Hide",() => { app.toggleVisible(); },"CmdOrCtrl+H");
dotgrid.controller.add("picker","*","Inspect",() => { app.inspect(); },"CmdOrCtrl+.");
dotgrid.controller.add("picker","*","Documentation",() => { dotgrid.controller.docs(); },"CmdOrCtrl+Esc");
dotgrid.controller.add("picker","*","Reset",() => { dotgrid.reset(); dotgrid.theme.reset(); },"CmdOrCtrl+Backspace");
dotgrid.controller.add("picker","*","Quit",() => { app.exit(); },"CmdOrCtrl+Q");
dotgrid.controller.addRole("picker","Edit","undo");
dotgrid.controller.addRole("picker","Edit","redo");
dotgrid.controller.addRole("picker","Edit","cut");
dotgrid.controller.addRole("picker","Edit","copy");
dotgrid.controller.addRole("picker","Edit","paste");
dotgrid.controller.addRole("picker","Edit","delete");
dotgrid.controller.addRole("picker","Edit","selectall");
dotgrid.controller.add("picker","Mode","Stop Picker Mode",() => { dotgrid.picker.stop(); },"Escape");
dotgrid.controller.commit();
dotgrid.install(document.body);
window.addEventListener('load', () => { dotgrid.start(); })
</script>
window.addEventListener('load', () => {
dotgrid.start()
dotgrid.acels.inject('Dotgrid')
})
</script>
</body>
</html>

View File

@ -2,15 +2,14 @@
function Cursor (dotgrid) {
this.pos = { x: 0, y: 0 }
this.lastPos = { x: 0, y: 0 }
this.translation = null
this.operation = null
this.translate = function (from = null, to = null, multi = false, copy = false, layer = false) {
if ((from || to) && this.translation === null) { this.translation = { multi: multi, copy: copy, layer: layer } }
if (from) { this.translation.from = from }
if (to) { this.translation.to = to }
if (!from && !to) {
this.translation = null
}
@ -18,49 +17,36 @@ function Cursor (dotgrid) {
this.down = function (e) {
this.pos = this.atEvent(e)
// Translation
if (dotgrid.tool.vertexAt(this.pos)) {
this.translate(this.pos, this.pos, e.shiftKey, e.ctrlKey || e.metaKey, e.altKey)
}
dotgrid.renderer.update()
dotgrid.interface.update()
e.preventDefault()
}
this.last_pos = { x: 0, y: 0 }
this.move = function (e) {
this.pos = this.atEvent(e)
// Translation
if (this.translation) {
this.translate(null, this.pos)
}
if (this.last_pos.x !== this.pos.x || this.last_pos.y !== this.pos.y) {
if (this.lastPos.x !== this.pos.x || this.lastPos.y !== this.pos.y) {
dotgrid.renderer.update()
}
dotgrid.interface.update()
this.lastPos = this.pos
e.preventDefault()
this.last_pos = this.pos
}
this.up = function (e) {
this.pos = this.atEvent(e)
if (this.translation && !isEqual(this.translation.from, this.translation.to)) {
if (this.translation.layer === true) { dotgrid.tool.translateLayer(this.translation.from, this.translation.to) } else if (this.translation.copy) { dotgrid.tool.translateCopy(this.translation.from, this.translation.to) } else if (this.translation.multi) { dotgrid.tool.translateMulti(this.translation.from, this.translation.to) } else { dotgrid.tool.translate(this.translation.from, this.translation.to) }
} else if (e.target.id === 'guide') {
dotgrid.tool.addVertex({ x: this.pos.x, y: this.pos.y })
dotgrid.picker.stop()
}
this.translate()
dotgrid.interface.update()
dotgrid.renderer.update()
e.preventDefault()
@ -68,15 +54,13 @@ function Cursor (dotgrid) {
this.alt = function (e) {
this.pos = this.atEvent(e)
dotgrid.tool.removeSegmentsAt(this.pos)
e.preventDefault()
setTimeout(() => { dotgrid.tool.clear() }, 150)
setTimeout(() => {
dotgrid.tool.clear()
}, 150)
}
// Position Mods
this.atEvent = function (e) {
return this.snapPos(this.relativePos({ x: e.clientX, y: e.clientY }))
}

View File

@ -12,12 +12,9 @@
/* global Picker */
/* global Cursor */
/* global webFrame */
/* global FileReader */
function Dotgrid () {
// ISU
this.install = function (host) {
console.info('Dotgrid', 'Installing..')
@ -35,7 +32,6 @@ function Dotgrid () {
host.appendChild(this.renderer.el)
// Add events
document.addEventListener('mousedown', (e) => { this.cursor.down(e) }, false)
document.addEventListener('mousemove', (e) => { this.cursor.move(e) }, false)
document.addEventListener('contextmenu', (e) => { this.cursor.alt(e) }, false)
@ -45,11 +41,12 @@ function Dotgrid () {
document.addEventListener('paste', (e) => { this.paste(e) }, false)
window.addEventListener('resize', (e) => { this.onResize() }, false)
window.addEventListener('dragover', (e) => { e.stopPropagation(); e.preventDefault(); e.dataTransfer.dropEffect = 'copy' })
window.addEventListener('drop', this.drag)
window.addEventListener('drop', this.onDrop)
this.acels.set('File', 'New', 'CmdOrCtrl+N', () => { this.source.new() })
this.acels.set('File', 'Save', 'CmdOrCtrl+S', () => { this.source.save('export.grid', this.tool.export(), 'text/plain') })
this.acels.set('File', 'Export Vector', 'CmdOrCtrl+E', () => { this.source.download('export.svg', this.manager.toString(), 'image/svg+xml') })
this.acels.set('File', 'Export Image', 'CmdOrCtrl+Shift+E', () => { this.manager.toPNG(this.tool.settings.size, (dataUrl) => { this.source.download('export.png', dataUrl, 'image/png') }) })
this.acels.set('File', 'Open', 'CmdOrCtrl+O', () => { this.source.open('grid', this.whenOpen) })
this.acels.set('File', 'Revert', 'CmdOrCtrl+W', () => { this.source.revert() })
this.acels.set('History', 'Undo', 'CmdOrCtrl+Z', () => { this.history.undo() })
@ -91,7 +88,7 @@ function Dotgrid () {
}
this.start = () => {
console.log('Ronin', 'Starting..')
console.log('Dotgrid', 'Starting..')
console.info(`${this.acels}`)
this.theme.start()
@ -124,25 +121,8 @@ function Dotgrid () {
this.update()
}
// Methods
this.modZoom = function (mod = 0, set = false) {
try {
const { webFrame } = require('electron')
const currentZoomFactor = webFrame.getZoomFactor()
webFrame.setZoomFactor(set ? mod : currentZoomFactor + mod)
console.log(window.devicePixelRatio)
} catch (err) {
console.log('Cannot zoom')
}
}
this.setZoom = function (scale) {
try {
webFrame.setZoomFactor(scale)
} catch (err) {
console.log('Cannot zoom')
}
this.whenOpen = (data) => {
this.tool.replace(JSON.parse(data))
}
// Resize Tools
@ -229,6 +209,16 @@ function Dotgrid () {
reader.readAsText(file)
}
this.onDrop = (e) => {
e.preventDefault()
e.stopPropagation()
const file = e.dataTransfer.files[0]
if (file.name.indexOf('.grid') > -1) {
this.source.load(e.dataTransfer.files[0], this.whenOpen)
}
}
this.copy = function (e) {
this.renderer.update()
@ -270,15 +260,8 @@ function Dotgrid () {
this.renderer.update()
}
function sizeOffset (a, b) { return { width: a.width - b.width, height: a.height - b.height } }
function printSize (size) { return `${size.width}x${size.height}` }
function isJson (text) { try { JSON.parse(text); return true } catch (error) { return false } }
function step (v, s) { return Math.round(v / s) * s }
}
String.prototype.capitalize = function () {
return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase()
}
function sizeOffset (a, b) { return { width: a.width - b.width, height: a.height - b.height } }
function printSize (size) { return `${size.width}x${size.height}` }
function isJson (text) { try { JSON.parse(text); return true } catch (error) { return false } }
function isEqual (a, b) { return a && b && a.x === b.x && a.y === b.y }
function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
function step (v, s) { return Math.round(v / s) * s }

View File

@ -1,5 +1,7 @@
'use strict'
/* global dotgrid */
function Generator (layer, style) {
this.layer = layer
this.style = style
@ -12,15 +14,12 @@ function Generator (layer, style) {
for (const k2 in seg.vertices) {
if (mirror === 1 || mirror === 3) { seg.vertices[k2].x = (dotgrid.tool.settings.size.width) - seg.vertices[k2].x }
if (mirror === 2 || mirror === 3) { seg.vertices[k2].y = (dotgrid.tool.settings.size.height) - seg.vertices[k2].y }
// Offset
seg.vertices[k2].x += offset.x
seg.vertices[k2].y += offset.y
// Rotate
const center = { x: (dotgrid.tool.settings.size.width / 2) + offset.x + (7.5), y: (dotgrid.tool.settings.size.height / 2) + offset.y + 30 }
seg.vertices[k2] = rotatePoint(seg.vertices[k2], center, angle)
// Scale
seg.vertices[k2].x *= scale
seg.vertices[k2].y *= scale
@ -42,7 +41,9 @@ function Generator (layer, style) {
const next = vertices[parseInt(id) + 1]
const afterNext = vertices[parseInt(id) + 2]
if (parseInt(id) === 0 && !prev || parseInt(id) === 0 && prev && (prev.x !== vertex.x || prev.y !== vertex.y)) {
if (parseInt(id) === 0 && !prev) {
html += `M${vertex.x},${vertex.y} `
} else if (parseInt(id) === 0 && prev && (prev.x !== vertex.x || prev.y !== vertex.y)) {
html += `M${vertex.x},${vertex.y} `
}

View File

@ -50,7 +50,7 @@ function Interface (dotgrid) {
html += `
<svg
id="option_${name}"
title="${name.capitalize()}"
title="${capitalize(name)}"
onmouseout="dotgrid.interface.out('${type}','${name}')"
onmouseup="dotgrid.interface.up('${type}','${name}')"
onmousedown="dotgrid.interface.down('${type}','${name}', event)"
@ -59,7 +59,7 @@ function Interface (dotgrid) {
class="icon ${type}">
<path id="${name}_path" class="icon_path" d="${tool.icon}"/>${name === 'depth' ? '<path class="icon_path inactive" d=""/>' : ''}
<rect ar="${name}" width="300" height="300" opacity="0">
<title>${name.capitalize()}${tool.key ? '(' + tool.key + ')' : ''}</title>
<title>${capitalize(name)}${tool.key ? '(' + tool.key + ')' : ''}</title>
</rect>
</svg>`
}
@ -152,4 +152,8 @@ function Interface (dotgrid) {
e.preventDefault()
}
}
function capitalize (str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
}
}

View File

@ -1,6 +1,9 @@
'use strict'
// Manages the SVG file
/* global XMLSerializer */
/* global btoa */
/* global Image */
/* global Blob */
function Manager (dotgrid) {
// Create SVG parts
@ -28,15 +31,9 @@ function Manager (dotgrid) {
const paths = dotgrid.tool.paths()
for (const id in this.layers) {
let style = styles[id]
let path = paths[id]
const style = styles[id]
const path = paths[id]
const layer = this.layers[id]
// Easter Egg
if (dotgrid.tool.settings.crest === true) {
style = styles[0]
path = paths[0]
layer.setAttribute('transform', `rotate(${parseInt(id) * 120} ${(dotgrid.tool.settings.size.width / 2) + 7.5} ${(dotgrid.tool.settings.size.height / 2) + 7.5})`)
}
layer.style.strokeWidth = style.thickness
layer.style.strokeLinecap = style.strokeLinecap
@ -67,7 +64,7 @@ function Manager (dotgrid) {
canvas.height = (size.height) * 2
img.onload = function () {
canvas.getContext('2d').drawImage(img, 0, 0, (size.width) * 2, (size.height) * 2)
callback(canvas.toDataURL('image/png'), 'export.png')
callback(canvas.toDataURL('image/png'))
}
img.src = image64
}

View File

@ -73,6 +73,7 @@ function Picker (dotgrid) {
}
this.onKeyDown = (e) => {
e.stopPropagation()
if (e.key === 'Enter') {
this.validate()
e.preventDefault()
@ -81,9 +82,7 @@ function Picker (dotgrid) {
if (e.key === 'Escape') {
this.stop()
e.preventDefault()
return
}
e.stopPropagation()
}
this.onKeyUp = (e) => {

View File

@ -1,5 +1,9 @@
'use strict'
/* global Image */
/* global Path2D */
/* global Generator */
function Renderer (dotgrid) {
this.el = document.createElement('canvas')
this.el.id = 'guide'
@ -68,14 +72,14 @@ function Renderer (dotgrid) {
this.drawMirror = function () {
if (!this.showExtras) { return }
if (dotgrid.tool.style().mirror_style === 0 && dotgrid.tool.settings.crest === false) { return }
if (dotgrid.tool.style().mirror_style === 0) { return }
const middle = { x: dotgrid.tool.settings.size.width, y: dotgrid.tool.settings.size.height }
if (dotgrid.tool.style().mirror_style === 1 || dotgrid.tool.style().mirror_style === 3 || dotgrid.tool.settings.crest === true) {
if (dotgrid.tool.style().mirror_style === 1 || dotgrid.tool.style().mirror_style === 3) {
this.drawRule({ x: middle.x, y: 15 * this.scale }, { x: middle.x, y: (dotgrid.tool.settings.size.height) * this.scale })
}
if (dotgrid.tool.style().mirror_style === 2 || dotgrid.tool.style().mirror_style === 3 || dotgrid.tool.settings.crest === true) {
if (dotgrid.tool.style().mirror_style === 2 || dotgrid.tool.style().mirror_style === 3) {
this.drawRule({ x: 15 * this.scale, y: middle.y }, { x: (dotgrid.tool.settings.size.width) * this.scale, y: middle.y })
}
}
@ -101,7 +105,6 @@ function Renderer (dotgrid) {
this.drawGrid = function () {
if (!this.showExtras) { return }
const cursor = { x: parseInt(dotgrid.cursor.pos.x / 15), y: parseInt(dotgrid.cursor.pos.y / 15) }
const markers = { w: parseInt(dotgrid.tool.settings.size.width / 15), h: parseInt(dotgrid.tool.settings.size.height / 15) }
for (let x = markers.w - 1; x >= 0; x--) {
@ -267,6 +270,5 @@ function Renderer (dotgrid) {
function printSize (size) { return `${size.width}x${size.height}` }
function sizeOffset (a, b) { return { width: a.width - b.width, height: a.height - b.height } }
function isEqual (a, b) { return a && b && Math.abs(a.x) === Math.abs(b.x) && Math.abs(a.y) === Math.abs(b.y) }
function clamp (v, min, max) { return v < min ? min : v > max ? max : v }
}

View File

@ -1,72 +0,0 @@
'use strict'
function Source (dotgrid) {
this.path = null
this.new = function () {
dotgrid.setZoom(1.0)
dotgrid.history.push(dotgrid.tool.layers)
dotgrid.clear()
this.path = null
}
this.open = function () {
if (!dialog) { return }
const paths = dialog.showOpenDialog({ properties: ['openFile'], filters: [{ name: 'Dotgrid Image', extensions: ['dot', 'grid'] }] })
if (!paths) { console.warn('Nothing to load'); return }
fs.readFile(paths[0], 'utf-8', (err, data) => {
if (err) { alert('An error ocurred reading the file :' + err.message); return }
this.load(paths[0], data)
})
}
this.load = function (path, data) {
if (!path || isJson(data) === false) { return }
const parsed = JSON.parse(`${data}`)
dotgrid.tool.replace(parsed)
this.path = path
}
this.save = function () {
if (dotgrid.tool.length() < 1) { console.warn('Nothing to save'); return }
if (this.canWrite() === true) {
this.write(this.path, dotgrid.tool.export())
} else {
dotgrid.manager.toGRID(grab)
}
}
this.canWrite = function () {
return fs && fs.existsSync(this.path)
}
this.write = function (path, data) {
console.log('Source', 'Writing ' + path)
fs.writeFile(path, data, (err) => {
if (err) { alert('An error ocurred updating the file' + err.message); console.warn(err) }
})
}
this.export = function () {
if (dotgrid.tool.length() < 1) { console.warn('Nothing to export'); return }
dotgrid.manager.toSVG(grab)
}
this.render = function () {
if (dotgrid.tool.length() < 1) { console.warn('Nothing to render'); return }
dotgrid.manager.toPNG({ width: dotgrid.tool.settings.size.width * 2, height: dotgrid.tool.settings.size.height * 2 }, grab)
}
function grab (base64, name) {
const link = document.createElement('a')
link.setAttribute('href', base64)
link.setAttribute('download', name)
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }))
}
function isJson (text) { try { JSON.parse(text); return true } catch (error) { return false } }
}

View File

@ -1,8 +1,10 @@
'use strict'
/* global Generator */
function Tool (dotgrid) {
this.index = 0
this.settings = { size: { width: 600, height: 300 }, crest: false }
this.settings = { size: { width: 600, height: 300 } }
this.layers = [[], [], []]
this.styles = [
{ thickness: 10, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#f00', fill: 'none', mirror_style: 0, transform: 'rotate(45)' },
@ -23,7 +25,6 @@ function Tool (dotgrid) {
}
this.reset = function () {
this.settings.crest = false
this.styles[0].mirror_style = 0
this.styles[1].mirror_style = 0
this.styles[2].mirror_style = 0
@ -119,7 +120,6 @@ function Tool (dotgrid) {
}
this.selectSegmentAt = function (pos, source = this.layer()) {
const target_segment = null
for (const segmentId in source) {
const segment = source[segmentId]
for (const vertexId in segment.vertices) {
@ -152,9 +152,9 @@ function Tool (dotgrid) {
}
this.addSegment = function (type, vertices, index = this.index) {
const append_target = this.canAppend({ type: type, vertices: vertices }, index)
if (append_target) {
this.layer(index)[append_target].vertices = this.layer(index)[append_target].vertices.concat(vertices)
const appendTarget = this.canAppend({ type: type, vertices: vertices }, index)
if (appendTarget) {
this.layer(index)[appendTarget].vertices = this.layer(index)[appendTarget].vertices.concat(vertices)
} else {
this.layer(index).push({ type: type, vertices: vertices })
}
@ -199,24 +199,16 @@ function Tool (dotgrid) {
dotgrid.renderer.update()
}
this.toggleCrest = function () {
this.settings.crest = this.settings.crest !== true
dotgrid.interface.update(true)
dotgrid.renderer.update()
}
this.misc = function (type) {
dotgrid.picker.start()
}
this.source = function (type) {
if (type === 'grid') { dotgrid.renderer.toggle() }
if (type === 'screen') { app.toggleFullscreen() }
if (type === 'open') { dotgrid.source.open() }
if (type === 'save') { dotgrid.source.save() }
if (type === 'render') { dotgrid.source.render() }
if (type === 'export') { dotgrid.source.export() }
if (type === 'open') { dotgrid.source.open('grid', dotgrid.whenOpen) }
if (type === 'save') { dotgrid.source.save('export.grid', dotgrid.tool.export(), 'text/plain') }
if (type === 'export') { dotgrid.source.download('export.svg', dotgrid.manager.toString(), 'image/svg+xml') }
if (type === 'render') { dotgrid.manager.toPNG(dotgrid.tool.settings.size, (dataUrl) => { dotgrid.source.download('export.png', dataUrl, 'image/png') }) }
}
this.canAppend = function (content, index = this.index) {
@ -353,9 +345,6 @@ function Tool (dotgrid) {
this.selectLayer = function (id) {
this.index = clamp(id, 0, 2)
if (this.index !== 0) { this.settings.crest = false }
this.clear()
dotgrid.renderer.update()
dotgrid.interface.update(true)