another push

Fixed issue with color saving
Redesigned color select section
This commit is contained in:
Jaman Brundage 2022-03-23 08:47:57 -04:00
parent 5f09ceddcf
commit 12a3283790
19 changed files with 281 additions and 117 deletions

View File

@ -85,9 +85,9 @@
#canvas-view {
bottom: 0px;
left: 48px;
right: 48px;
top: 48px;
left: var(--top-nav-height);
right: var(--top-nav-height);
top: var(--top-nav-height);
cursor: default;
position: fixed;
display: block;
@ -97,9 +97,9 @@
box-shadow: inset 0px 0px 4px 0px rgba(0, 0, 0, 0.4);
position: fixed;
bottom: 0px;
left: 48px;
right: 48px;
top: 48px;
left: var(--top-nav-height);
right: var(--top-nav-height);
top: var(--top-nav-height);
display: block;
pointer-events: none;
}

View File

@ -1,36 +1,57 @@
#colors-menu {
right: 200px;
width: 48px;
width:var(--layers-width);
display: flex;
justify-content: flex-start;
flex-direction: column;
flex-direction: row;
list-style-type: none;
top: 48px;
bottom: 0;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
height: var(--palette-height);
padding: 0;
margin: 0;
background-color: $basecolor;
box-sizing: border-box;
position: fixed;
align-items: flex-start;
z-index: 1120;
overflow-y: scroll;
resize: vertical;
li {
width: 48px;
flex-basis: 48px;
width: var(--top-nav-height);
height: var(--top-nav-height);
flex-basis: var(--top-nav-height);
&:not(.noshrink) {
flex-grow: 1;
}
&.noshrink {
flex-grow: 0;
flex-shrink: 0;
}
}
svg {
margin-top: 4px;
}
&::-webkit-scrollbar {
background: #232125;
width: 1em;
}
&::-webkit-scrollbar-track {
margin-top: -0.125em;
width: 1em;
}
&::-webkit-scrollbar-thumb {
background: #332f35;
border-radius: 0.25em;
border: solid 0.125em #232125; //same color as scrollbar back to fake padding
}
&::-webkit-scrollbar-corner {
background: #232125;
}
scrollbar-color: #332f35 #232125;
scroll-behavior: smooth;
}
//added when the color is a duplicate of another
#duplicate-color-warning {
display: inline-block;
@ -118,14 +139,14 @@
content: "";
display: block;
position: absolute;
top: -3px;
left: -3px;
top: 0px;
left: 0px;
border: solid 3px #fff;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 0px 3px rgba(0, 0, 0, 0.15) inset;
z-index: 10;
box-sizing: border-box;
} //inner outline
&.selected button::after {
content: "";
@ -149,7 +170,9 @@
background: $basehover;
}
.jscolor-wrap {
z-index: 10000 !important;
}
.jscolor-picker-bottom {
display: none;
@ -173,7 +196,6 @@
}
}
.delete-color-button {
background: none;
padding: 0px;

24
css/_containers.scss Normal file
View File

@ -0,0 +1,24 @@
#right-container{
display: flex;
flex-direction: column;
position: fixed;
top: var(--top-nav-height);
right: var(--top-nav-height);
bottom: 0;
}
#bottom-container{
display: flex;
flex-direction: column;
position: fixed;
left: 0;
right: 0;
bottom: 0;
}
#left-container{
display: flex;
flex-direction: column;
position: fixed;
top: var(--top-nav-height);
bottom: 0;
left: var(--top-nav-height);
}

View File

@ -43,4 +43,15 @@ svg {
#data-holders, .preload {
display: none;
}
}
#right-nav {
position: fixed;
top: var(--top-nav-height);
right: 0;
bottom: 0;
width: var(--layers-width);
z-index: 9000;
display: flex;
flex-direction: column;
}

View File

@ -1,4 +1,3 @@
#layer-properties-menu {
visibility: hidden;
margin: 0;
@ -8,7 +7,7 @@
width: 120px;
text-align: center;
margin-right: 200px;
margin-right: var(--layers-width);
/*border:1px solid $basetext;*/
list-style: none;
position: relative;
@ -72,19 +71,16 @@
}
scrollbar-color: #332f35 #232125;
scroll-behavior: smooth;
width:200px;
top: 48px;
bottom: 0;
right:0;
width:var(--layers-width);
padding: 0;
margin: 0;
background-color: $basecolor;
box-sizing: border-box;
position: fixed;
z-index: 1120;
list-style-type: none;
overflow-y:scroll;
overflow-x:hidden;
flex: 1;
#add-layer-button {
path {
fill: $baseicon;
@ -112,6 +108,33 @@
color: $basehovertext;
background-color: $basehover;
}
#add-reference-button {
path {
fill: $baseicon;
}
svg {
position: relative;
margin-right: 10px;
}
position:relative;
justify-content: center;
display:none;
align-items:center;
margin-top:2px;
font-size: 1.2em;
color: $basetext;
height: 100%;
width: 100%;
padding: 17px;
background: none;
border: none;
cursor: pointer;
}
#add-reference-button:hover {
color: $basehovertext;
background-color: $basehover;
}
}
.selected-layer {

View File

@ -1,6 +1,6 @@
#main-menu {
height: 48px;
height: var(--top-nav-height);
left: 0;
right: 0;
list-style-type: none;
@ -35,7 +35,7 @@
li ul {
display: none;
position: absolute;
top: 48px;
top: var(--top-nav-height);
list-style-type: none;
padding: 0;
margin: 0;

View File

@ -6,6 +6,18 @@
font-style: italic;
}
#new-pixel-inventory {
display: none;
}
#new-pixel-map {
display: none;
}
#new-voxel-world {
display: none;
}
.dimentions-x {
margin: -2px 7px;
path {
@ -13,12 +25,10 @@
}
}
#no-palette-button {
display: none;
}
#editor-mode-info {
font-style: italic;
}

View File

@ -1,9 +1,9 @@
#tools-menu {
left: 0;
width: 48px;
width: var(--top-nav-height);
list-style-type: none;
top: 48px;
top: var(--top-nav-height);
bottom: 0;
padding: 0;
margin: 0;
@ -24,7 +24,7 @@
width: 100%;
padding: 0;
cursor: pointer;
height: 48px;
height: var(--top-nav-height);
z-index:0;
}
@ -73,7 +73,7 @@
#tools-menu .size-buttons {
position:absolute;
display: none;
height:48px;
height:var(--top-nav-height);
left:8px;
z-index:-1;
background-color: $basecolor !important;
@ -140,8 +140,8 @@
#tool-tutorial {
display:inline-block;
position:absolute;
margin-left:48px;
margin-top:48px;
margin-left:var(--top-nav-height);
margin-top:var(--top-nav-height);
background-color: $basehover;
color:$basetext;
font-size:14px;

View File

@ -13,4 +13,12 @@ $baseselected: lighten($basecolor, 15%); //color(selectedTool, background),
$baseselectediconhover: lighten($basecolor, 70%); //color(subbutton, foreground, hover)
$baseselectedhover: lighten($basecolor, 25%); //color(subbutton, background, hover)
$indent: darken($basecolor, 5%); //color(indent)
$indenttext: lighten($basecolor, 50%); //color(indent, foreground)
$indenttext: lighten($basecolor, 50%); //color(indent, foreground)
:root{
--layers-width: 206px;
--palette-height: 38%;
--top-nav-height: 48px;
--drag-bar-size: var(--top-nav-height);
}

View File

@ -13,6 +13,16 @@ const ColorModule = (() => {
document.getElementById('jscolor-hex-input').addEventListener('change',colorChanged, false);
document.getElementById('jscolor-hex-input').addEventListener('input', colorChanged, false);
document.getElementById('add-color-button').addEventListener('click', addColorButtonEvent, false);
// const resizeObserver = new ResizeObserver(function(mutations) {
// console.log('mutations:', mutations);
// const h = mutations[0].contentRect.height;
// colorMenuResized(h);
// });
// resizeObserver.observe(document.getElementById('colors-menu'), {attributes:true});
// function colorMenuResized(h) {
// document.getElementById('layers-menu').style.height = `calc(100% + ${h}px - var(--top-nav-height))`;
// }
// Making the colours in the HTML menu sortable
new Sortable(document.getElementById("colors-menu"), {
@ -21,7 +31,6 @@ const ColorModule = (() => {
draggable: ".draggable-colour",
onEnd: function() {Events.simulateMouseEvent(window, "mouseup");}
});
/** Changes all of one color to another after being changed from the color picker
*
* @param {*} colorHexElement The element that has been changed
@ -94,18 +103,25 @@ const ColorModule = (() => {
*
* @param {*} e The event that triggered the callback
*/
function clickedColor (e){
function clickedColor (e) {
//left clicked color
if (e.which == 1) {
// remove current color selection
const currentSelectedColorButton = document.querySelector('#colors-menu li.selected .color-button');
const selectedColor = currentSelectedColorButton.style.backgroundColor;
const clickedColor = e.target.style.backgroundColor;
document.querySelector('#colors-menu li.selected')?.classList.remove('selected');
//set current color
updateCurrentColor(Color.cssToHex(e.target.style.backgroundColor));
updateCurrentColor(Color.cssToHex(clickedColor));
//make color selected
e.target.parentElement.classList.add('selected');
if(selectedColor === clickedColor) {
e.target.parentElement.lastChild.classList.add('hidden');
e.target.jscolor.show();
}
}
//right clicked color
else if (e.which == 3) {
@ -251,7 +267,6 @@ const ColorModule = (() => {
//loop through colors
for (var i = 0; i < colors.length; i++) {
//////console.log(color,'=',colors[i].jscolor.toString());
if (color == colors[i].jscolor.toString()) {
//set color to the color button
@ -334,7 +349,11 @@ const ColorModule = (() => {
}
function getCurrentPalette() {
return currentPalette;
let ret = [...currentPalette];
if(ret.length === 0) {
ret = [...document.querySelectorAll(".color-button")].map(n=>n.style.backgroundColor);
}
return ret;
}
function resetPalette() {
@ -346,7 +365,6 @@ const ColorModule = (() => {
* @param {*} paletteColors The colours of the palette
*/
function createColorPalette(paletteColors) {
////console.log("creating palette");
//remove current palette
while (colorsMenu.childElementCount > 1)
colorsMenu.children[0].remove();
@ -358,7 +376,6 @@ const ColorModule = (() => {
for (var i = 0; i < paletteColors.length; i++) {
var newColor = new Color("hex", paletteColors[i]);
var newColorElement = ColorModule.addColor(newColor.hex);
////console.log('newColor.hex === ',newColor.hex);
var newColRgb = newColor.rgb;
var lightestColorRgb = lightestColor.rgb;
@ -383,7 +400,6 @@ const ColorModule = (() => {
//set as current color
updateCurrentColor(darkestColor.hex);
////console.log('getCurrentPalette() === ',getCurrentPalette());
}
/** Creates the palette with the colours used in all the layers
@ -423,7 +439,6 @@ const ColorModule = (() => {
//create palette from colors array
createColorPalette(colorPaletteArray);
////console.log("Done 2");
}
function updateCurrentColor(color, refLayer) {

View File

@ -18,8 +18,6 @@ const EditorState = (() => {
//switch to advanced mode
if (newMode == 'Advanced') {
Events.emit("switchedToAdvanced");
// Hide the palette menu
document.getElementById('colors-menu').style.right = '200px'
pixelEditorMode = 'Advanced';
document.getElementById("switch-mode-button").innerHTML = 'Switch to basic mode';

View File

@ -128,10 +128,14 @@ const FileManager = (() => {
function localStorageSave() {
const lpeStr = getProjectData();
const lpe = JSON.parse(lpeStr);
//console.log('LPE saved === ',lpe);
console.log('BEFORE JSON.stringify(lpe.colors,null,4) === ',JSON.stringify(lpe.colors,null,4));
console.log([...ColorModule.getCurrentPalette()]);
if(lpe.colors.length < 1)lpe.colors = [...ColorModule.getCurrentPalette()];
if(lpe.colors.length < 1)lpe.colors.push("#000000");
console.log('AFTER JSON.stringify(lpe.colors,null,4) === ',JSON.stringify(lpe.colors,null,4));
if(!lpe.canvasWidth)lpe.canvasWidth = 16;
if(!lpe.canvasHeight)lpe.canvasHeight = 16;
console.log('LPE saved === ',lpe);
localStorage.setItem("lpe-cache", JSON.stringify(lpe));
}
function localStorageReset() {
@ -185,6 +189,7 @@ const FileManager = (() => {
// If it's a Lospec Pixel Editor tm file, I load the project
if (extension == 'lpe') {
openProject();
// openFile();
}
else {
openFile();
@ -204,6 +209,7 @@ const FileManager = (() => {
img.onload = function() {
//create a new pixel with the images dimentions
console.log('this === ',this);
Startup.newPixel({
canvasWidth: this.width,
canvasHeight: this.height
@ -224,23 +230,26 @@ const FileManager = (() => {
fileReader.readAsDataURL(browseHolder.files[0]);
}
function openProject(lpeData) {
console.log('lpeData === ',lpeData);
// Getting all the data
if(lpeData){
_parseLPE(lpeData);
} else {
let file = uri ?? browseHolder.files[0];
let file = browseHolder.files[0];
let reader = new FileReader();
reader.readAsText(file, "UTF-8");
// Converting the data to a json object and creating a new pixel (see _newPixel.js for more)
reader.onload = function (e) {
console.log('this === ',this);
console.log('e === ',e);
let dictionary = JSON.parse(e.target.result);
console.log('FileManager.js => openProject => loaded lpe dictionary === ',dictionary);
_parseLPE(dictionary);
}
reader.readAsText(file, "UTF-8");
}
function _parseLPE(dictionary) {
Startup.newPixel(dictionary, true);
Startup.newPixel(dictionary);
}
}
function loadFromLPE(dictionary) {
@ -248,38 +257,11 @@ const FileManager = (() => {
//console.log('dictionary === ',dictionary);
dictionary = FileManager.upgradeLPE(dictionary);
EditorState.switchMode(dictionary.editorMode ?? 'Advanced');
// I add every layer the file had in it
// dictionary.layers.forEach((layerData,i)=>{
// let layerImage = layerData.src;
// if (layerData != null) {
// // Setting id
// let createdLayer = LayerList.addLayer(layerData.id, false, layerData.name);
// // Setting name
// createdLayer.menuEntry.getElementsByTagName("p")[0].innerHTML = layerData.name;
// // Adding the image (I can do that because they're sorted by increasing z-index)
// let img = new Image();
// img.onload = function() {
// createdLayer.context.drawImage(img, 0, 0);
// createdLayer.updateLayerPreview();
// };
// img.src = layerImage;
// // Setting visibility and lock options
// if (!layerData.isVisible) {
// createdLayer.hide();
// }
// if (layerData.isLocked) {
// createdLayer.lock();
// }
// }
// })
if(dictionary.colors)ColorModule.createColorPalette(dictionary.colors);
// Startup.newPixel(dictionary);
}
function getProjectData() {
// use a dictionary
@ -355,7 +337,7 @@ const FileManager = (() => {
browsePaletteHolder.value = null;
}
function upgradeLPE(dictionary) {
////console.log('dictionary === ',dictionary);
console.log('dictionary === ',dictionary);
if(dictionary.color0 && !dictionary.colors) {
dictionary.colors = [];
let colorIdx = 0;
@ -364,8 +346,9 @@ const FileManager = (() => {
delete dictionary[`color${colorIdx}`];
colorIdx++;
}
console.log('Object.keys(dictionary) === ',Object.keys(dictionary));
dictionary.layers = Object.keys(dictionary).reduce((r,k,i)=>{
if(k.slice(0,5) === "layer"){
if(k.slice(0,5) === "layer" && dictionary[k]){
if(dictionary[k].isSelected){
dictionary.selectedLayer = r.length;
}
@ -379,7 +362,9 @@ const FileManager = (() => {
}
return r;
},[]);
console.log('dictionary.layers === ',dictionary.layers);
}
console.log('dictionary === ',dictionary);
return dictionary;
}
function toggleCache(elm){
@ -395,7 +380,7 @@ const FileManager = (() => {
const cacheEnabled = !!Number(localStorage.getItem("lpe-cache-enabled"));
document.getElementById("auto-cache-button").textContent = cacheBtnText(cacheEnabled);
return {
const ret = {
cacheEnabled,
loadFromLPE,
toggleCache,
@ -413,4 +398,14 @@ const FileManager = (() => {
openSaveProjectWindow,
open
};
Object.keys(ret).forEach(k=>{
if(typeof ret[k] === "function"){
const orig = ret[k];
ret[k] = function() {
DEBUG_ARR.push(`called FileManager -> ${k}`);
return orig.call(this,...arguments);
}
}
})
return ret;
})();

View File

@ -6,6 +6,7 @@ const LayerList = (() => {
let dragStartLayer;
Events.on("mousedown", layerList, openOptionsMenu);
Events.on('click',"add-layer-button", addLayerClick, false);
Events.on('click',"add-reference-button", addReferenceClick, false);
Events.onCustom("switchedToAdvanced", showLayerList);
Events.onCustom("switchedToBasic", hideLayerList);
@ -28,6 +29,10 @@ const LayerList = (() => {
layerList.style.display = "none";
document.getElementById('layer-button').style.display = 'none';
}
function addReferenceClick(id, saveHistory = true, layerName) {
addLayer(...arguments);
currFile.layers[currFile.layers.length-1].selectLayer();
}
function addLayerClick(id, saveHistory = true, layerName) {
addLayer(...arguments);
currFile.layers[currFile.layers.length-1].selectLayer();
@ -156,14 +161,6 @@ const LayerList = (() => {
dragStartLayer = getLayerByID(layerList.children[event.oldIndex].id);
}
function getLayerByID(id) {
//console.log(`getLayerByID(${id})`);
// for (let i=0; i<currFile.layers.length; i++) {
// if (currFile.layers[i].hasCanvas()) {
// if (currFile.layers[i].menuEntry.id == id) {
// return currFile.layers[i];
// }
// }
// }
let ret;
for (let i=0; i<currFile.layers.length; i++) {
if (currFile.layers[i].hasCanvas()) {
@ -172,8 +169,6 @@ const LayerList = (() => {
}
}
}
//console.log('ret === ',ret);
return ret ?? null;
}
function getLayerByName(name) {
@ -200,19 +195,9 @@ const LayerList = (() => {
renamingLayer = true;
}
function duplicateLayer(event, saveHistory = true) {
function getMenuEntryIndex(list, entry) {
for (let i=0; i<list.length; i++) {
if (list[i] === entry) {
return i;
}
}
return -1;
}
let layerIndex = currFile.layers.indexOf(currFile.currentLayer);
// Creating a new canvas
let newCanvas = document.createElement("canvas");
// Setting up the new canvas

View File

@ -1,3 +1,4 @@
let DEBUG_ARR = [];
const Startup = (() => {
let splashPostfix = '';
@ -31,11 +32,13 @@ const Startup = (() => {
* @param {*} skipModeConfirm If skipModeConfirm == true, then the mode switching confirmation will be skipped
*/
function newPixel (lpe = null, skipModeConfirm = false) {
console.log('called newPixel');
DEBUG_ARR.push('called Startup -> newPixel');
console.trace();
// The palette is empty, at the beginning
ColorModule.resetPalette();
lpe = FileManager.upgradeLPE(lpe);
initLayers(lpe);
initPalette();
@ -60,6 +63,7 @@ const Startup = (() => {
////console.trace();
}
function clearLayers() {
DEBUG_ARR.push('called Startup -> clearLayers');
console.dir(currFile.layers);
for(let i = currFile.layers.length-1; i >= 0;i--) {
currFile.layers[i].delete(i);
@ -70,6 +74,7 @@ const Startup = (() => {
}
}
function initLayers(lpe) {
DEBUG_ARR.push('called Startup -> initLayers');
//console.group('called initLayers');
//console.log('currFile.layers === ',currFile.layers);
@ -150,6 +155,7 @@ const Startup = (() => {
}
function initPalette() {
DEBUG_ARR.push('called Startup -> initPalette');
// Get selected palette
let selectedPalette = Util.getText('palette-button' + splashPostfix);
@ -197,6 +203,7 @@ const Startup = (() => {
}
function resetInput() {
DEBUG_ARR.push('called Startup -> resetInput');
//reset new form
Util.setValue('size-width', 64);
Util.setValue('size-height', 64);
@ -206,6 +213,7 @@ const Startup = (() => {
}
function newFromTemplate(preset, x, y) {
DEBUG_ARR.push('called Startup -> newFromTemplate');
if (preset != '') {
const presetProperties = PresetModule.propertiesOf(preset);
Util.setText('palette-button-splash', presetProperties.palette);
@ -219,6 +227,7 @@ const Startup = (() => {
}
function splashEditorMode(mode) {
DEBUG_ARR.push('called Startup -> splashEditorMode');
editorMode = mode;
}

View File

@ -47,6 +47,9 @@ const ToolManager = (() => {
if (!EditorState.documentCreated || Dialogue.isOpen())
return;
const isHoveringMenuElement = !!mouseEvent.path.find(n=>n.id && n.id.includes("-menu"));
if(isHoveringMenuElement)return;
let mousePos = Input.getCursorPosition(mouseEvent);
tools["zoom"].onMouseWheel(mousePos, mouseEvent.deltaY < 0 ? 'in' : 'out');
}

View File

@ -5,7 +5,9 @@
//=include data/consts.js
//=include data/palettes.js
// str.split(`//=include `).slice(1).map(n=>{
// return `<script src="${jsPath}/${n.split('\n')[0]}"></script>`;
// });
/** UTILITY AND INPUT **/
//=include Util.js
//=include Events.js

53
old_lpe1.json Normal file
View File

@ -0,0 +1,53 @@
{
"canvasWidth": 128,
"canvasHeight": 128,
"editorMode": "Advanced",
"color0": "#798040",
"color1": "#33ff69",
"color2": "#2f748a",
"nLayers": 7,
"layer4": {
"canvas": {},
"context": {
"mozImageSmoothingEnabled": false
},
"isSelected": false,
"isVisible": true,
"isLocked": false,
"oldLayerName": null,
"menuEntry": {},
"id": "layer1",
"name": "Layer 0"
},
"layer4ImageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAABCRJREFUeF7tmrFx3DAQRXXlOFYDjtyLS3BkOXIJ7sWRG1DscuShZjADcwgSBD4ofO5TouCIvd3 / H3ZB8h5P / IVW4BG6eop / AoDgEAAAAARXIHj5dAAACK5A8PLpAAAQXIHg5dMBACC4AsHLpwMAQHAFgpdPBwCA4AoEL58OAADBFQhePh0AAIIrELx8OgAABFcgePl0AAAIrkDw8ukAABBcgeDl0wEAILgCwcunAwBAcAWCl08HAIDgCgQvnw4AAPEU + Pby + W2v6t / fP21 + /Pr4dbsNc7uCjnDeMz8Z/ + XH380wP1 / +3E6 vqQp6fvv6vjNH7bSS + UfGJxoA4Gh7dX4 + CoBe4wGg09ja5SMAWJufz / dSqy / lSweodbLxOjUAufm1bX4vdQBoNLZm2WL + MvvT / 5 o1e9ck8xXGMwJ63ahYrwYgdZOzbZ4OUGHWiEuUACyxlMbTAUY4voqpAmCU + Uu6nAEGgtALwIiWvy4XAAYBkB / 8 Wg6Bac3RI97e9AGgV8HC + h4ArjKfETDI / CVsS / vPnxmM3vkcAgea3wLAekxcBUCrDDOPjileBp3pAG7mzz46rABwNH / 28 TENAItQpdfApXcEs7f + fGTMOgamB6B0W + hk / sxjYBoAtnb / 3 jMBAGg9kv6 / bloAjh4IAcBNANia70fmL6UDwE0BqDFfAYDydwI1VnAI3FBpff9fa34PAFcbz23gzvbIAdi7DdwKcXYEfJTxAHDwAqj1d4C1AHy08QCwA0Da9Wdafwp3BMAsxgNAYfbnLV8JwGzGA8DO4S991AtAz2 / 9 a07wimu4C6g4DJ4ROp0dljUjfgB6JpeaawFAAICb6XnJANAIQG56 / r7g6BBYsyuvvAYADtTOjc4vLb0iBgANvlO8DGop5WoA0g7u + d4ZuwAAFOgrmQUALdv1RmsA4EZmtpTSA8D6 + 2 YYCbYjoMU8xRoAUKhoHAMAjM1TpA4AChWNYwCAsXmK1AFAoaJxDAAwNk + ROgAoVDSOAQDG5ilSBwCFiuYxVBDwJNAUBAAwNU6VNgColDSNAwCmxinT7oVghvm / 6 MHbwA4qeiAAgA7hWapTgA6g09IyEgBY2qZLGgB0WlpGAgBL23RJA4BOS8tIAGBpmy5pANBpaRkJACxt0yUNADotLSMBgKVtuqQBQKelZSQAsLRNlzQA6LS0jAQAlrbpkgYAnZaWkQDA0jZd0gCg09IyEgBY2qZLGgB0WlpGAgBL23RJA4BOS8tIAGBpmy5pANBpaRkJACxt0yUNADotLSMBgKVtuqQBQKelZSQAsLRNlzQA6LS0jAQAlrbpkgYAnZaWkQDA0jZd0gCg09IyEgBY2qZLGgB0WlpGAgBL23RJA4BOS8tIAGBpmy5pANBpaRkJACxt0yUNADotLSMBgKVtuqQBQKelZaR / PIgEn3reoTUAAAAASUVORK5CYII = ",
"layer5": {
"canvas": {},
"context": {
"mozImageSmoothingEnabled": false
},
"isSelected": false,
"isVisible": true,
"isLocked": false,
"oldLayerName": null,
"menuEntry": {},
"id": "layer6",
"name": "Layer 1"
},
"layer5ImageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAA7ZJREFUeF7tnFFyo0AQQ + Mz7an2RDnVnilbqYqrHMo2aNBgLL380gMj6XUDdpLLBz / VDlyq1SP + AwDKIQAAACh3oFw + EwAAyh0ol88EAIByB8rlMwEAoNyBcvlMAAAod6BcPhMAAModKJfPBACAcgfK5TMBAKDcgXL5TAAAKHegXD4TAADKHSiXzwQAgHIHyuUzAQCg3IFy + UwAACh3oFw + EwAAyh0ol88EAIByB8rlMwEAoNyBcvlMAAAod6BcPhMAAModKJfPBPgB4M / X3y + FhX + XzwjvIkQowS1r1eCv6wFgj + snWTsa / vf2AeAkIY5uY0 / 4 ADDq + knW7Q0fAE4S5Mg2HOEDwIjzJ1jjCh8AThCmugVn + G4ARvfmeBCteA0cNfgZZHvNd + xp7x6 + 9 QGAOkp + 6 lXzHYEvt6ru4Z7UeABmGL / 1 FjDr2s4Po6IBmBnAo + 6 beU0mgDiuZ4WxDH / Wddbkcgt44tCMUK6Gzzj3Wtj3jgPAA9fOEtBIqMoaALjjVkv4Wx9E14CKewgEgLXIfx + PAqApfCbAAvS28AEAACy / lBJzC2ACaPf + azUAjPn28lWOV8CoL4PaJgAAlD8DAEAxAK7wuQUccCef8cURAJz8I + DZXxUDwAkB2BKK40F1y3WUwcZroOLWTa0ahCN816d / t5IBQABADf321A4A9lz / kUwAeAKAy3BH + DO6n7eARfiuwJdMOQCYtbeYCSBM8kNLHeHP6v6oCXBoqsLFHADM6n4AEIIcKXWEP7P7AWAkVWGNA4CZ3Q8AQphqqSP82d0PAGqqQr0DgNndDwBCoEqpI / wjuh8AlFSFWgcAR3Q / AAihbi11hH9U9wPA1lSFOgcAR3U / AAjBbil1hH9k9wPAllSFGgcAR3Y / AAjhrpU6wj + 6 + wFgLVXhuAOAo7sfAISA10oBYM2h8ON7AXhF9zMBjFACgNHMdzzVHgBe1f1MACNpAGA08x1PNQrAK7ufCWAkDQCMZr7jqQDgHVMz7nkEgFePf24BANDx7 + KNOcedij8MiYtUEwQAml9x1QAQF6kmCAA0v + KqASAuUk0QAGh + xVUDQFykmiAA0PyKqwaAuEg1QQCg + RVXDQBxkWqCAEDzK64aAOIi1QQBgOZXXDUAxEWqCQIAza + 4 agCIi1QTBACaX3HVABAXqSYIADS / 4 qoBIC5STRAAaH7FVQNAXKSaIADQ / IqrBoC4SDVBAKD5FVcNAHGRaoIAQPMrrhoA4iLVBAGA5ldcNQDERaoJAgDNr7jq / yPDGJDPZGMlAAAAAElFTkSuQmCC ",
"layer6": {
"canvas": {},
"context": {
"mozImageSmoothingEnabled": false
},
"isSelected": true,
"isVisible": true,
"isLocked": false,
"oldLayerName": null,
"menuEntry": {},
"id": "layer7",
"name": "Layer 2"
},
"layer6ImageData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAA9VJREFUeF7tnFuO1TAQRGdWxOYQi0BsjhWBrsQVmSgPt92VVNxnfse4y1UnZQshPj / 4 Ke3AZ + nTc / gPACgOAQAAQHEHih + fBgCA4g4UPz4NAADFHSh + fBoAAIo7UPz4NAAAFHeg + PFpAAAo7kDx49MAAFDcgeLHpwEAoLgDxY9PAwBAcQeKH58GAIDiDhQ / fqkG + Pb9559o3r9 //Zjao6kPtw67B4DlHjPCUAaA0fC3mmMGIAAgeiccrH8iECUAUHz9R9w8CQQASGyA9VZPAGF6AK7++p/2VgAAYQNEGiEKala7AMCFALxG7QUHAIIgoqYKJOxuuQYhqpUGaEgramrDlqlLliFGtQJAQxRRUxu2TF/yDrJHawYEU78BekxNT1i4IQAcmDt7+EcPyghz0zYAALRhAAAbPo08ztpsz1nFFSC6AraMdWwUANgBYCSsM1NH9s757v/vcqa1Zd6UV8BISK2mjsxoCaZlTavWo70AYOVO1NQ7QYhq3QIBABau9Bp6FwS9epcgAEACAO8trgYBAJIfgRmGXglBht7pGmAkgAxDX0yOaGh5/L3XZOgFgH9uZpi5Dk8NQoZmABACoG4DANjoy96vLsPMvfru1XR2HWRopgHEDaBsAQBIaoAMI8++VkULZOimAQ7+oeZZqNHfZ0MAAA9qAMVfFgEAAAw3+PAG0RpUr++p2YwvKXKuHo1b+2foBoAL3wDLEEchyAj/pac8AFlGRhog4z2QpRsAbv4vYHqaICt8GuCm+u9pC9WfoQFubgBVsK37AgAAtLLyjHXROzXzPn2GQ19V0gA0wBO53ddMA8TypAFogBgx7qtpgFhCNAANECPGfTUNEEuIBqABYsS4r6YBYgnRADRAjBj31TRALCEagAaIEeO+mgaIJUQD0AAxYtxX0wCxhGgAGiBGDKvncmC6BpgrHv1pAEDvsfUEALCORy8OAPQeW08AAOt49OIAQO+x9QQAsI5HLw4A9B5bTwAA63j04gBA77H1BACwjkcvDgD0HltPAADrePTiAEDvsfUEALCORy8OAPQeW08AAOt49OIAQO+x9QQAsI5HLw4A9B5bTwAA63j04gBA77H1BACwjkcvDgD0HltPAADrePTiAEDvsfUEALCORy8OAPQeW08AAOt49OIAQO+x9QQAsI5HLw4A9B5bTwAA63j04gBA77H1BACwjkcvDgD0HltPAADrePTiAEDvsfUEALCORy8OAPQeW08AAOt49OIAQO+x9QQAsI5HLw4A9B5bTwAA63j04gBA77H1BACwjkcvDgD0HltPAADrePTi/gKPB0SQMNaI5gAAAABJRU5ErkJggg=="
}

View File

@ -18,8 +18,11 @@
{{> main-menu}}
{{> tools-menu}}
{{> colors-menu}}
{{> layers-menu}}
<div id="right-nav">
{{> colors-menu}}
{{> layers-menu}}
</div>
{{> tool-previews}}
{{> canvases}}

View File

@ -24,6 +24,9 @@
<button id="add-layer-button">
{{svg "plus.svg" width="20" height="20"}} Add layer
</button>
<button id="add-reference-button">
{{svg "plus.svg" width="20" height="20"}} Add reference
</button>
</li>
</ul>