some quick fixes for older browsers/documentation

Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
Victor Seiji Hariki 2022-12-18 11:26:47 -03:00
parent 072e81ce5e
commit d571eca7b0
No known key found for this signature in database
GPG key ID: 53D76502731B4A7C
6 changed files with 124 additions and 26 deletions

View file

@ -199,5 +199,5 @@
} }
.expand-button:hover { .expand-button:hover {
backdrop-filter: brightness(60%); background-color: #293d3d77;
} }

View file

@ -343,10 +343,7 @@ function newImage(evt) {
clearPaintedMask(); clearPaintedMask();
uil.layers.forEach(({layer}) => { uil.layers.forEach(({layer}) => {
commands.runCommand("eraseImage", "Clear Canvas", { commands.runCommand("eraseImage", "Clear Canvas", {
x: -layer.origin.x, ...layer.bb,
y: -layer.origin.y,
w: layer.canvas.width,
h: layer.canvas.height,
ctx: layer.ctx, ctx: layer.ctx,
}); });
}); });

View file

@ -143,8 +143,6 @@ const uiCtx = uiCanvas.getContext("2d", {desynchronized: true});
debugLayer.hide(); // Hidden by default debugLayer.hide(); // Hidden by default
layers.registerCollection("mask", {name: "Mask Layers", requiresActive: true});
// Where CSS and javascript magic happens to make the canvas viewport work // Where CSS and javascript magic happens to make the canvas viewport work
/** /**
* The global viewport object (may be modularized in the future). All * The global viewport object (may be modularized in the future). All

47
js/lib/layers.d.js Normal file
View file

@ -0,0 +1,47 @@
/**
* A layer
*
* @typedef {object} Layer
* @property {string} id The id of the layer
* @property {string} key A identifier for the layer
* @property {string} name The display name of the layer
* @property {BoundingBox} bb The current bounding box of the layer, in layer coordinates
* @property {Size} resolution The resolution of the layer (canvas)
* @property {boolean} full If the layer is a full layer (occupies the full collection)
* @property {number} x The x coordinate of the layer
* @property {number} y The y coordinate of the layer
* @property {number} width The width of the layer
* @property {number} w The width of the layer
* @property {number} height The height of the layer
* @property {number} h The height of the layer
* @property {Point} origin The location of the origin ((0, 0) point) of the layer (If canvas goes from -64, -32 to 128, 512, it's (64, 32))
* @property {HTMLCanvasElement} canvas The canvas element of the layers
* @property {CanvasRenderingContext2D} ctx The context of the canvas of the layer
* @property {function} clear Clears the layer contents
* @property {function} moveAfter Moves this layer to another level (after given layer)
* @property {function} moveBefore Moves this layer to another level (before given layer)
* @property {function} moveTo Moves this layer to another location
* @property {function} resize Resizes the layer in place
* @property {function} hide Hides the layer
* @property {function} unhide Unhides the layer
*/
/**
* A layer collection
*
* @typedef {object} LayerCollection
* @property {string} id The id of the collection
* @property {string} key A identifier for the collection
* @property {string} name The display name of the collection
* @property {HTMLDivElement} element The base element of the collection
* @property {HTMLDivElement} inputElement The element used for input handling for the collection
* @property {Point} inputOffset The offset for calculating layer coordinates from input element input information
* @property {Point} origin The location of the origin ((0, 0) point) of the collection (If canvas goes from -64, -32 to 128, 512, it's (64, 32))
* @property {BoundingBox} bb The current bounding box of the collection, in layer coordinates
* @property {{[key: string]: Layer}} layers An object for quick access to named layers of the collection
* @property {Size} size The size of the collection (CSS)
* @property {Size} resolution The resolution of the collection (canvas)
* @property {function} expand Expands the collection and its full layers by the specified amounts
* @property {function} registerLayer Registers a new layer
* @property {function} deleteLayer Deletes a layer from the collection
*/

View file

@ -31,6 +31,18 @@
}; };
}); });
// Add basic get bounding box support (canvas coordinates)
Reflect.defineProperty(CanvasRenderingContext2D.prototype, "bb", {
get: function () {
return new BoundingBox({
x: -this.origin.x,
y: -this.origin.y,
w: this.canvas.width,
h: this.canvas.height,
});
},
});
// Modifying drawImage // Modifying drawImage
Reflect.defineProperty(CanvasRenderingContext2D.prototype, "drawImage", { Reflect.defineProperty(CanvasRenderingContext2D.prototype, "drawImage", {
value: function (...args) { value: function (...args) {
@ -161,6 +173,18 @@ const layers = {
// Registers a new collection // Registers a new collection
// Layer collections are a group of layers (canvases) that are rendered in tandem. (same width, height, position, transform, etc) // Layer collections are a group of layers (canvases) that are rendered in tandem. (same width, height, position, transform, etc)
/**
*
* @param {string} key A key used to identify the collection
* @param {Size} size The initial size of the collection in pixels (CSS size)
* @param {object} options Extra options for the collection
* @param {string} [options.name=key] The display name of the collection
* @param {{key: string, options: object}} [options.initLayer] The configuration for the initial layer to be created
* @param {number} [options.inputSizeMultiplier=9] Size of the input area element, in pixels
* @param {HTMLElement} [options.targetElement] Element the collection will be inserted into
* @param {Size} [options.resolution=size] The resolution of the collection (canvas size). Not sure it works.
* @returns {LayerCollection} The newly created layer collection
*/
registerCollection: (key, size, options = {}) => { registerCollection: (key, size, options = {}) => {
defaultOpt(options, { defaultOpt(options, {
// Display name for the collection // Display name for the collection
@ -208,6 +232,7 @@ const layers = {
options.targetElement.appendChild(element); options.targetElement.appendChild(element);
/** @type {LayerCollection} */
const collection = makeWriteOnce( const collection = makeWriteOnce(
{ {
id, id,
@ -217,6 +242,7 @@ const layers = {
_layers: [], _layers: [],
layers: {}, layers: {},
key,
name: options.name, name: options.name,
element, element,
inputElement: inputel, inputElement: inputel,
@ -230,6 +256,15 @@ const layers = {
return {...this._origin}; return {...this._origin};
}, },
get bb() {
return new BoundingBox({
x: -this.origin.x,
y: -this.origin.y,
w: this.size.w,
h: this.size.h,
});
},
_resizeInputDiv() { _resizeInputDiv() {
// Set offset // Set offset
const oldOffset = {...this._inputOffset}; const oldOffset = {...this._inputOffset};
@ -269,6 +304,14 @@ const layers = {
} }
}, },
/**
* Expands the collection and its full layers by the specified amounts
*
* @param {number} left Pixels to expand left
* @param {number} top Pixels to expand top
* @param {number} right Pixels to expand right
* @param {number} bottom Pixels to expand bottom
*/
expand(left, top, right, bottom) { expand(left, top, right, bottom) {
this._layers.forEach((layer) => { this._layers.forEach((layer) => {
if (layer.full) layer._expand(left, top, right, bottom); if (layer.full) layer._expand(left, top, right, bottom);
@ -301,7 +344,7 @@ const layers = {
* @param {?string} options.group * @param {?string} options.group
* @param {object} options.after * @param {object} options.after
* @param {object} options.ctxOptions * @param {object} options.ctxOptions
* @returns * @returns {Layer} The newly created layer
*/ */
registerLayer(key = null, options = {}) { registerLayer(key = null, options = {}) {
// Make ID // Make ID
@ -398,7 +441,11 @@ const layers = {
_logpath: _layerlogpath, _logpath: _layerlogpath,
_collection: collection, _collection: collection,
bb: new BoundingBox(options.bb), _bb: new BoundingBox(options.bb),
get bb() {
return new BoundingBox(this._bb);
},
resolution: new Size(options.resolution), resolution: new Size(options.resolution),
id, id,
key, key,
@ -420,27 +467,27 @@ const layers = {
), ),
get x() { get x() {
return this.bb.x; return this._bb.x;
}, },
get y() { get y() {
return this.bb.y; return this._bb.y;
}, },
get width() { get width() {
return this.bb.w; return this._bb.w;
}, },
get height() { get height() {
return this.bb.h; return this._bb.h;
}, },
get w() { get w() {
return this.bb.w; return this._bb.w;
}, },
get h() { get h() {
return this.bb.h; return this._bb.h;
}, },
get origin() { get origin() {
@ -451,6 +498,16 @@ const layers = {
canvas, canvas,
ctx, ctx,
/**
* This is called by the collection when the layer must be expanded.
*
* Should NOT be called directly
*
* @param {number} left Pixels to expand left
* @param {number} top Pixels to expand top
* @param {number} right Pixels to expand right
* @param {number} bottom Pixels to expand bottom
*/
_expand(left, top, right, bottom) { _expand(left, top, right, bottom) {
const tmpCanvas = document.createElement("canvas"); const tmpCanvas = document.createElement("canvas");
tmpCanvas.width = this.w; tmpCanvas.width = this.w;
@ -509,8 +566,8 @@ const layers = {
* @param {number} y Y coordinate of the top left of the canvas * @param {number} y Y coordinate of the top left of the canvas
*/ */
moveTo(x, y) { moveTo(x, y) {
this.bb.x = x; this._bb.x = x;
this.bb.y = y; this._bb.y = y;
this.canvas.style.left = `${x}px`; this.canvas.style.left = `${x}px`;
this.canvas.style.top = `${y}px`; this.canvas.style.top = `${y}px`;
}, },
@ -528,8 +585,8 @@ const layers = {
canvas.height = Math.round( canvas.height = Math.round(
options.resolution.h * (h / options.bb.h) options.resolution.h * (h / options.bb.h)
); );
this.bb.w = w; this._bb.w = w;
this.bb.h = h; this._bb.h = h;
canvas.style.width = `${w}px`; canvas.style.width = `${w}px`;
canvas.style.height = `${h}px`; canvas.style.height = `${h}px`;
}, },
@ -571,7 +628,11 @@ const layers = {
return layer; return layer;
}, },
// Deletes a layer /**
* Deletes a layer from the collection
*
* @param {Layer} layer Layer to delete
*/
deleteLayer: (layer) => { deleteLayer: (layer) => {
const lobj = collection._layers.splice( const lobj = collection._layers.splice(
collection._layers.findIndex( collection._layers.findIndex(

View file

@ -363,12 +363,7 @@ function cropCanvas(sourceCanvas, options = {}) {
function downloadCanvas(options = {}) { function downloadCanvas(options = {}) {
defaultOpt(options, { defaultOpt(options, {
cropToContent: true, cropToContent: true,
canvas: uil.getVisible({ canvas: uil.getVisible(imageCollection.bb),
x: -imageCollection.origin.x,
y: -imageCollection.origin.y,
w: imageCollection.size.w,
h: imageCollection.size.h,
}),
filename: filename:
new Date() new Date()
.toISOString() .toISOString()