Browse Source

lazygit

feature/modules
Gregory Leeman 7 months ago
parent
commit
cdea98e7a0
  1. 6
      .eslintrc.json
  2. 27
      eslint.config.js
  3. 14
      index.html
  4. 4
      main.js
  5. 139
      package-lock.json
  6. 3
      package.json
  7. 95
      scripts/canvas.js
  8. 90
      scripts/color.js
  9. 16
      scripts/layer.js
  10. 4
      scripts/main.js
  11. 243
      styles/archive.css
  12. 194
      styles/main.css

6
.eslintrc.json

@ -1,6 +0,0 @@
{
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
}
}

27
eslint.config.js

@ -1,8 +1,21 @@
import globals from "globals";
import pluginJs from "@eslint/js";
// For ES Module Syntax
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
];
{
languageOptions: {
ecmaVersion: "latest", // Or specify a specific version like 2021, 2020, etc.
sourceType: "module", // "module" for ES modules, "script" for non-modular code
globals: {
// Define global variables that are predefined
browser: true,
node: true,
es6: true,
},
},
rules: {
"no-unused-vars": "off",
"semi": ["error", "always"],
"quotes": ["error", "double"]
}
}
];

14
index.html

@ -6,17 +6,21 @@
<link rel="stylesheet" href="styles/main.css">
</head>
<body>
<div id="menu-bar"></div>
<div id="menu-bar" class="bar"></div>
<div id="row">
<div id="tool-bar"></div>
<div id="tool-bar" class="bar"></div>
<div id="studio">
<div id="easel"></div>
</div>
<div id="layer-bar">
<div id="layer-bar" class="bar">
<div id="layer-controllers"></div>
</div>
</div>
<div id="color-bar"></div>
<script src="scripts/render.js"></script>
<div id="color-bar" class="bar"></div>
<script src="scripts/mixbox.js"></script>
<script src="scripts/color.js"></script>
<script src="scripts/canvas.js"></script>
<script src="scripts/layer.js"></script>
<script src="scripts/main.js"></script>
</body>
</html>

4
main.js

@ -1,7 +1,7 @@
// main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
import { app, BrowserWindow } from 'electron';
import path from 'path';
function createWindow() {
const mainWindow = new BrowserWindow({

139
package-lock.json

@ -8,9 +8,8 @@
"name": "mixx",
"version": "1.0.0",
"devDependencies": {
"@eslint/js": "^9.9.0",
"electron": "^31.3.1",
"eslint": "^9.9.0",
"eslint": "^9.9.1",
"globals": "^15.9.0",
"nodemon": "^3.1.4"
}
@ -73,9 +72,9 @@
}
},
"node_modules/@eslint/config-array": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz",
"integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==",
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz",
"integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==",
"dev": true,
"dependencies": {
"@eslint/object-schema": "^2.1.4",
@ -122,9 +121,9 @@
}
},
"node_modules/@eslint/js": {
"version": "9.9.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz",
"integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==",
"version": "9.9.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.1.tgz",
"integrity": "sha512-xIDQRsfg5hNBqHz04H1R3scSVwmI+KUbqjsQKHKQ1DAUSaUjYPReZZmS/5PNiKu1fUvzDd6H7DEDKACSEhu+TQ==",
"dev": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -252,12 +251,12 @@
}
},
"node_modules/@types/node": {
"version": "20.14.15",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
"integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==",
"version": "20.16.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.1.tgz",
"integrity": "sha512-zJDo7wEadFtSyNz5QITDfRcrhqDvQI1xQNQ0VoizPjM/dVAODqqIUWbJPkvsxmTI0MYRGRikcdjMPhOssnPejQ==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
"undici-types": "~6.19.2"
}
},
"node_modules/@types/responselike": {
@ -467,27 +466,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/chalk/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
},
"node_modules/chalk/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@ -512,6 +490,18 @@
"fsevents": "~2.3.2"
}
},
"node_modules/chokidar/node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
@ -665,9 +655,9 @@
"optional": true
},
"node_modules/electron": {
"version": "31.3.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.3.1.tgz",
"integrity": "sha512-9fiuWlRhBfygtcT+auRd/WdBK/f8LZZcrpx0RjpXhH2DPTP/PfnkC4JB1PW55qCbGbh4wAgkYbf4ExIag8oGCA==",
"version": "31.4.0",
"resolved": "https://registry.npmjs.org/electron/-/electron-31.4.0.tgz",
"integrity": "sha512-YTwKoAA+nrJMlI1TTHnIXLYWoQLKnhbkz0qxZcI7Hadcy0UaFMFs9xzwvH2MnrRpVJy7RKo49kVGuvSdRl8zMA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@ -743,16 +733,16 @@
}
},
"node_modules/eslint": {
"version": "9.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz",
"integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==",
"version": "9.9.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.1.tgz",
"integrity": "sha512-dHvhrbfr4xFQ9/dq+jcVneZMyRYLjggWjk6RVsIiHsP8Rz6yZ8LvZ//iU4TrZF+SXWG+JkNF2OyiZRvzgRDqMg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.11.0",
"@eslint/config-array": "^0.17.1",
"@eslint/config-array": "^0.18.0",
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "9.9.0",
"@eslint/js": "9.9.1",
"@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.3.0",
"@nodelib/fs.walk": "^1.2.8",
@ -829,18 +819,6 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.3"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/espree": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz",
@ -1089,15 +1067,15 @@
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.1"
"is-glob": "^4.0.3"
},
"engines": {
"node": ">= 6"
"node": ">=10.13.0"
}
},
"node_modules/global-agent": {
@ -1205,12 +1183,12 @@
"dev": true
},
"node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"engines": {
"node": ">=4"
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
@ -1553,6 +1531,15 @@
"url": "https://opencollective.com/nodemon"
}
},
"node_modules/nodemon/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/nodemon/node_modules/semver": {
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
@ -1565,6 +1552,18 @@
"node": ">=10"
}
},
"node_modules/nodemon/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@ -1995,15 +1994,15 @@
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"dependencies": {
"has-flag": "^3.0.0"
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=4"
"node": ">=8"
}
},
"node_modules/text-table": {
@ -2065,9 +2064,9 @@
"dev": true
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true
},
"node_modules/universalify": {

3
package.json

@ -8,9 +8,8 @@
"start": "nodemon --exec electron ."
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"electron": "^31.3.1",
"eslint": "^9.9.0",
"eslint": "^9.9.1",
"globals": "^15.9.0",
"nodemon": "^3.1.4"
}

95
scripts/canvas.js

@ -1,28 +1,25 @@
import { Color } from './color.js';
/* global makeColor */
function disableImageSmoothing({ctx}) {
ctx.imageSmoothingEnabled = false;
if (ctx.imageSmoothingEnabled !== false) {
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false; ctx.msImageSmoothingEnabled = false;
}
};
class Canvas extends HTMLCanvasElement { // {{{
constructor({height=600, width=800}) {
super();
this.ctx = this.getContext('2d');
this.temp = document.createElement('canvas');
this.temp.ctx = this.temp.getContext('2d');
this.resize({height, width});
}
function makeCanvas({height, width}) {
const canvas = document.createElement("canvas");
canvas.ctx = this.getContext("2d");
canvas.temp = document.createElement("canvas");
canvas.temp.ctx = this.temp.getContext("2d");
canvas.resize({height, width});
getData() {
canvas.getData = function() {
return this.ctx.getImageData(0, 0, this.width, this.height).data;
}
};
fromDataUrl({dataUrl}) {
canvas.fromDataUrl = function({dataUrl}) {
const image = new Image();
image.src = dataUrl;
image.onload = () => {
@ -34,54 +31,49 @@ class Canvas extends HTMLCanvasElement { // {{{
disableImageSmoothing(this.ctx);
};
return this;
}
};
setHeight({height}) {
canvas.setHeight = function({height}) {
this.height = height;
this.style.height = `${height}px`;
disableImageSmoothing(this.ctx);
return this;
}
};
setWidth({width}) {
canvas.setWidth = function({width}) {
this.width = width;
this.style.width = `${width}px`;
disableImageSmoothing(this.ctx);
return this;
}
};
resize({height, width}) {
canvas.resize = function({height, width}) {
this.height = height;
this.width = width;
this.style.height = `${height}px`;
this.style.width = `${width}px`;
disableImageSmoothing(this.ctx);
return this;
}
};
clear() {
canvas.clear = function() {
this.ctx.clearRect(0, 0, this.width, this.height);
return this;
}
};
fill({color}) {
canvas.fill = function({color}) {
this.ctx.fillStyle = color.toRgbaString();
this.ctx.fillRect(0, 0, this.width, this.height);
return this;
}
};
getColorAtPixel({x, y}) {
canvas.getColorAtPixel = function({x, y}) {
const data = this.getData();
const index = (y * this.width + x) * 4;
return new Color().fromRgbaArray({
r: data[index],
g: data[index + 1],
b: data[index + 2],
a: data[index + 3]
});
}
return makeColor({r: data[index], g: data[index + 1], b: data[index + 2], a: data[index + 3]});
};
setColorAtPixel({x, y, color}) {
canvas.setColorAtPixel = function({x, y, color}) {
const data = this.getData();
const index = (y * this.width + x) * 4;
const rgbaArray = color.toRgbaArray();
@ -90,9 +82,9 @@ class Canvas extends HTMLCanvasElement { // {{{
data[index + 2] = rgbaArray[2]; // blue
data[index + 3] = rgbaArray[3]; // alpha
return this;
}
};
drawLineWithPixels({x1, y1, x2, y2, color}) {
canvas.drawLineWithPixels = function({x1, y1, x2, y2, color}) {
const dx = Math.abs(x2 - x1);
const dy = Math.abs(y2 - y1);
const sx = x1 < x2 ? 1 : -1;
@ -106,9 +98,9 @@ class Canvas extends HTMLCanvasElement { // {{{
if (e2 < dx) { err += dx; y1 += sy; }
}
return this;
}
};
drawEmptyRectangle({x, y, width, height, color}) {
canvas.drawEmptyRectangle = function({x, y, width, height, color}) {
this.ctx.fillStyle = color.toRgbaString();
for (let x1 = x; x1 < x + width; x1++) {
this.setPixel(x1, y, color.toRgbaArray());
@ -123,18 +115,18 @@ class Canvas extends HTMLCanvasElement { // {{{
this.setPixel(x + width, y1, color.toRgbaString());
}
return this;
}
};
drawRectangle({x, y, width, height, color}) {
canvas.drawRectangle = function({x, y, width, height, color}) {
for (let x1 = x; x1 < x + width; x1++) {
for (let y1 = y; y1 < y + height; y1++) {
this.setPixel(x1, y1, color.toRgbaString());
}
}
return this;
}
};
drawEmptyCircle({x, y, diameter, color}) {
canvas.drawEmptyCircle = function({x, y, diameter, color}) {
const radius = Math.floor(diameter / 2);
for (let y1 = -radius; y1 <= radius; y1++) {
for (let x1 = -radius; x1 <= radius; x1++) {
@ -144,9 +136,9 @@ class Canvas extends HTMLCanvasElement { // {{{
}
}
return this;
}
};
drawCircle({x, y, diameter, color}) {
canvas.drawCircle = function({x, y, diameter, color}) {
if (diameter === 1) {
this.drawPixel(x, y, color.toRgbaString());
}
@ -161,9 +153,9 @@ class Canvas extends HTMLCanvasElement { // {{{
}
}
return this;
}
};
drawLineWithCircles({x1, y1, x2, y2, diameter, color}) {
canvas.drawLineWithCircles = function({x1, y1, x2, y2, diameter, color}) {
const dx = x2 - x1;
const dy = y2 - y1;
const distance = Math.sqrt(dx * dx + dy * dy);
@ -174,9 +166,9 @@ class Canvas extends HTMLCanvasElement { // {{{
this.drawCircle(x, y, diameter, color.toRgbaString());
}
return this;
}
};
floodFill({x, y, color}) {
canvas.floodFill = function({x, y, color}) {
const targetColor = this.getColorAtPixel(x, y);
const fillColor = color;
@ -196,10 +188,9 @@ class Canvas extends HTMLCanvasElement { // {{{
}
}
return this;
}
};
}
return canvas;
// }}}
}
export { Canvas, };

90
scripts/color.js

@ -1,76 +1,76 @@
import mixbox from './mixbox.js';
/* exported makeColor */
class Color {
constructor() {
this.r = 0;
this.g = 0;
this.b = 0;
this.a = 0;
}
function makeColor({r=0, g=0, b=0, a=255}) {
const color = {};
color.r = r;
color.g = g;
color.b = b;
color.a = a;
fromRgbaArray({rgbaArray}) {
this.r = rgbaArray[0];
this.g = rgbaArray[1];
this.b = rgbaArray[2];
this.a = rgbaArray[3];
color.fromRgbaArray = function({rgbaArray}) {
color.r = rgbaArray[0];
color.g = rgbaArray[1];
color.b = rgbaArray[2];
color.a = rgbaArray[3];
return color;
}
toRgbaArray() {
return [this.r, this.g, this.b, this.a];
color.toRgbaArray = function() {
return [color.r, color.g, color.b, color.a];
}
fromRgbaString({rgbaString}) {
this.r = rgbaString.split(',')[0].split('(')[1];
this.g = rgbaString.split(',')[1];
this.b = rgbaString.split(',')[2];
this.a = rgbaString.split(',')[3].split(')')[0];
color.fromRgbaString = function({rgbaString}) {
color.r = rgbaString.split(',')[0].split('(')[1];
color.g = rgbaString.split(',')[1];
color.b = rgbaString.split(',')[2];
color.a = rgbaString.split(',')[3].split(')')[0];
return color;
}
toRgbaString() {
return `rgba(${this.r},${this.g},${this.b},${this.a})`;
color.toRgbaString = function() {
return `rgba(${color.r},${color.g},${color.b},${color.a})`;
}
fromRgbString(rgbString) {
this.r = rgbString.split(',')[0].split('(')[1];
this.g = rgbString.split(',')[1];
this.b = rgbString.split(',')[2].split(')')[0];
this.a = 255;
color.fromRgbString = function(rgbString) {
color.r = rgbString.split(',')[0].split('(')[1];
color.g = rgbString.split(',')[1];
color.b = rgbString.split(',')[2].split(')')[0];
color.a = 255;
return color;
}
toRgbString() {
return `rgb(${this.r},${this.g},${this.b})`;
color.toRgbString = function() {
return `rgb(${color.r},${color.g},${color.b})`;
}
matchRgbArray({rgbArray, tolereance = 2}) {
const color1RgbArray = this.toRgbArray();
cosnt color2RgbArray = rgbArray;
return
Math.abs(color1RgbArray[0] - color2RgbArray[0]) <= tolerance &&
color.matchRgbArray = function({rgbArray, tolerance = 2}) {
const color1RgbArray = color.toRgbArray();
const color2RgbArray = rgbArray;
return Math.abs(color1RgbArray[0] - color2RgbArray[0]) <= tolerance &&
Math.abs(color1RgbArray[1] - color2RgbArray[1]) <= tolerance &&
Math.abs(color1RgbArray[2] - color2RgbArray[2]) <= tolerance;
}
matchColor({color}) {
return this.matchRgbArray({rgbArray: color.toRgbArray()});
color.matchColor = function({color}) {
return color.matchRgbArray({rgbArray: color.toRgbArray()});
}
mixxRgbArray({rgbArray, t}) {
const color1RgbArray = this.toRgbArray();
color.mixxRgbArray = function({rgbArray, t}) {
const color1RgbArray = color.toRgbArray();
const color2RgbArray = rgbArray;
var color3RgbArray;
if (this.matchRgbArray({rgbArray: color2RgbArray})) {
if (color.matchRgbArray({rgbArray: color2RgbArray})) {
color3RgbArray = color2RgbArray;
} else {
color3RgbArray = mixbox.lerp(color2, color2, t);
color3RgbArray = mixbox.lerp(color1RgbArray, color2RgbArray, t);
}
this.fromRgbArray(color3RgbArray);
return this;
return color.fromRgbArray(color3RgbArray);
}
mixxColor({color, t}) {
this.mixxRgbArray({rgbArray: color.toRgbArray(), t});
color.mixxColor = function({color, t}) {
color.mixxRgbArray({rgbArray: color.toRgbArray(), t});
}
}
export { Color, };

16
scripts/layer.js

@ -1,7 +1,4 @@
import { Canvas } from './canvas.js';
import { Color } from './color.js';
class Layer { // {{{
class Layer {
constructor({height=600, width=800}) {
this.drawCanvas = new Canvas({height, width});
this.selectCanvas = new Canvas({height, width});
@ -40,9 +37,7 @@ class Layer { // {{{
}
// }}}
class Layers { // {{{
class Layers {
constructor({easelElement, controllersElement, height=600, width=800, backgroundColor=new Color(255, 255, 255)}) {
this.backgroundColor = backgroundColor;
this.height = height;
@ -55,6 +50,7 @@ class Layers { // {{{
new Layer({height: this.height, width: this.width})
];
this.activeIndex = 1;
this.refresh();
}
@ -156,6 +152,7 @@ class Layers { // {{{
refreshEasel() {
this.easelElement.innerHTML = '';
this.layers.forEach(layer => {
console.log("test");
this.easelElement.appendChild(layer.drawCanvas);
this.easelElement.appendChild(layer.selectCanvas);
});
@ -238,13 +235,10 @@ class Layers { // {{{
}
refresh() {
console.log("test");
this.refreshEasel();
this.refreshControllers();
this.refreshPreviews();
}
}
// }}}
export { Layer, Layers };

4
scripts/render.js → scripts/main.js

@ -39,6 +39,8 @@ let isMouseDown = false;
let interval;
var startTime;
document.on
const layers = new Layers({
easelElement: easelElement,
controllersElement: layerControllersElement,
@ -53,7 +55,7 @@ const tools = new Tools({
tools.addTool({ // brush {{{
name: 'Brush',
key: 'b',
iconPath: 'icons/brush.png',
iconPath: 'icons/brush.svg',
mouseMove: () => {
const canvas = layers.getActive().selectCanvas;
canvas

243
styles/archive.css

@ -0,0 +1,243 @@
:root {
--white: #FFFFFF;
--button: #DDE4E7;
--hover: #B3BBBD;
--active: #8F9598;
/* --background: #7E888B; */
--background: #949C9E;
--black: #000000;
}
@font-face {
font-family: 'VT323';
src: url('fonts/VT323-Regular.ttf') format('truetype');
}
div {
box-sizing: border-box;
}
body {
margin: 0;
overflow: hidden;
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
font-family: 'VT323', monospace;
background-color: var(--background);
color: var(--black);
}
#menu-bar,
#info-bar,
#tool-bar,
#layer-bar {
z-index: 2;
}
#menu-bar {
justify-content: space-between;
}
#menu-bar, #info-bar {
padding: 10px;
background-color: var(--button);
display: flex;
flex-direction: row;
gap: 10px;
justify-content: flex-start;
flex-wrap: wrap;
}
#menu-bar {
order: 1;
}
#info-bar {
order: 3;
}
#tool-bar, #layer-bar {
display: flex;
padding: 10px;
padding-top: 0;
padding-bottom: 0;
background-color: var(--button);
gap: 10px;
height: 100%;
flex-direction: column;
justify-content: flex-start;
}
#studio {
flex-grow: 1;
height: 100%;
border: 1px solid;
cursor: crosshair;
}
#easel {
position: absolute;
border: 1px solid;
z-index: -1;
}
.button {
background-color: var(--button);
border: 1px solid;
border-radius: 2px;
cursor: pointer;
display: flex;
text-align: center;
justify-content: center;
}
.button:hover {
background-color: var(--hover);
}
.button.active, .button:active {
background-color: var(--active);
}
.bar-button {
position: relative;
flex-shrink: 0;
width: 30px;
height: 30px;
padding: 5px;
flex-direction: column;
}
.puck {
position: relative;
flex-shrink: 0;
width: 30px;
height: 30px;
border: 1px solid;
border-radius: 2px;
}
.key-hint {
display: block;
height: 13px;
width: 9px;
line-height: 8px;
position: absolute;
top: 2px;
left: 1px;
font-size: 1em;
justify-content: center;
text-align: center;
border-radius: 0 0 5px 0;
text-shadow:
1px 1px 0 #000,
-1px 1px 0 #000,
-1px -1px 0 #000,
1px -1px 0 #000;
color: var(--white);
pointer-events: none;
}
#layer-controllers {
background-color: var(--background);
border: 1px solid;
height: 100%;
}
.layer-controller {
background-color: var(--button);
height: 40px;
width: 90px;
border: 1px solid;
border-radius: 2px;
padding: 2px;
position: relative;
margin: 1px;
display: flex;
flex-direction: row;
gap: 2px;
align-items: center;
justify-content: space-between;
}
.layer-controller.active {
background-color: var(--active);
}
.layer-controller:hover {
background-color: var(--hover);
}
.layer-add-button {
background-color: var(--button);
height: 12px;
width: 100%;
border: 1px solid;
border-radius: 2px;
position: relative;
margin: 1px;
text-align: center;
font-size: .7em;
cursor: pointer;
}
.layer-add-button:hover {
background-color: var(--hover);
}
.top-left {
top: 0;
left: 0;
}
.bottom-right {
bottom: 0;
right: 0;
}
.top-right {
top: 0;
right: 0;
}
.bottom-left {
bottom: 0;
left: 0;
}
.layer-preview {
width: 30px;
height: 30px;
border: 1px solid;
object-fit: contain;
background-color: var(--background);
cursor: pointer;
}
.layer-move-buttons, .layer-merge-buttons {
font-size: .7em;
display: flex;
flex-direction: column;
gap: 2px;
flex-grow: 1;
height: 100%;
}
.layer-delete-button {
font-size: .7em;
flex-grow: 1;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.layer-move-button, .layer-merge-button {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
}

194
styles/main.css

@ -3,7 +3,6 @@
--button: #DDE4E7;
--hover: #B3BBBD;
--active: #8F9598;
/* --background: #7E888B; */
--background: #949C9E;
--black: #000000;
}
@ -29,52 +28,28 @@ body {
color: var(--black);
}
#menu-bar,
#info-bar,
#tool-bar,
#layer-bar {
.bar {
z-index: 2;
}
#menu-bar {
justify-content: space-between;
}
#menu-bar, #info-bar {
padding: 10px;
background-color: var(--button);
display: flex;
flex-direction: row;
gap: 10px;
justify-content: flex-start;
flex-wrap: wrap;
}
#menu-bar {
order: 1;
}
#info-bar {
order: 3;
padding: 10px;
}
#row {
display: flex;
flex-direction: row;
flex-grow: 1;
order: 2;
}
#menu-bar, #color-bar {
flex-direction: row;
}
#tool-bar, #layer-bar {
display: flex;
padding: 10px;
padding-top: 0;
padding-bottom: 0;
background-color: var(--button);
gap: 10px;
height: 100%;
flex-direction: column;
justify-content: flex-start;
}
#studio {
@ -96,160 +71,3 @@ canvas {
left: 0;
}
.button {
background-color: var(--button);
border: 1px solid;
border-radius: 2px;
cursor: pointer;
display: flex;
text-align: center;
justify-content: center;
}
.button:hover {
background-color: var(--hover);
}
.button.active, .button:active {
background-color: var(--active);
}
.bar-button {
position: relative;
flex-shrink: 0;
width: 30px;
height: 30px;
padding: 5px;
flex-direction: column;
}
.puck {
position: relative;
flex-shrink: 0;
width: 30px;
height: 30px;
border: 1px solid;
border-radius: 2px;
}
.key-hint {
display: block;
height: 13px;
width: 9px;
line-height: 8px;
position: absolute;
top: 2px;
left: 1px;
font-size: 1em;
justify-content: center;
text-align: center;
border-radius: 0 0 5px 0;
text-shadow:
1px 1px 0 #000,
-1px 1px 0 #000,
-1px -1px 0 #000,
1px -1px 0 #000;
color: var(--white);
pointer-events: none;
}
#layer-controllers {
background-color: var(--background);
border: 1px solid;
height: 100%;
}
.layer-controller {
background-color: var(--button);
height: 40px;
width: 90px;
border: 1px solid;
border-radius: 2px;
padding: 2px;
position: relative;
margin: 1px;
display: flex;
flex-direction: row;
gap: 2px;
align-items: center;
justify-content: space-between;
}
.layer-controller.active {
background-color: var(--active);
}
.layer-controller:hover {
background-color: var(--hover);
}
.layer-add-button {
background-color: var(--button);
height: 12px;
width: 100%;
border: 1px solid;
border-radius: 2px;
position: relative;
margin: 1px;
text-align: center;
font-size: .7em;
cursor: pointer;
}
.layer-add-button:hover {
background-color: var(--hover);
}
.top-left {
top: 0;
left: 0;
}
.bottom-right {
bottom: 0;
right: 0;
}
.top-right {
top: 0;
right: 0;
}
.bottom-left {
bottom: 0;
left: 0;
}
.layer-preview {
width: 30px;
height: 30px;
border: 1px solid;
object-fit: contain;
background-color: var(--background);
cursor: pointer;
}
.layer-move-buttons, .layer-merge-buttons {
font-size: .7em;
display: flex;
flex-direction: column;
gap: 2px;
flex-grow: 1;
height: 100%;
}
.layer-delete-button {
font-size: .7em;
flex-grow: 1;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.layer-move-button, .layer-merge-button {
flex-grow: 1;
display: flex;
flex-direction: column;
justify-content: center;
}

Loading…
Cancel
Save