Fix bounding box issues

This commit is contained in:
Skyler Lehmkuhl 2025-01-10 01:33:15 -05:00
parent 3819988d5e
commit 94f887efb1
2 changed files with 107 additions and 29 deletions

View File

@ -1437,6 +1437,7 @@ let actions = {
groupUuid: uuidv4(), groupUuid: uuidv4(),
parent: context.activeObject.idx, parent: context.activeObject.idx,
frame: context.activeObject.currentFrame.idx, frame: context.activeObject.currentFrame.idx,
layer: context.activeObject.activeLayer.idx,
position: { position: {
x: (bbox.x.min + bbox.x.max) / 2, x: (bbox.x.min + bbox.x.max) / 2,
y: (bbox.y.min + bbox.y.max) / 2, y: (bbox.y.min + bbox.y.max) / 2,
@ -1452,6 +1453,21 @@ let actions = {
let frame = action.frame let frame = action.frame
? pointerList[action.frame] ? pointerList[action.frame]
: parent.currentFrame; : parent.currentFrame;
let layer;
if (action.layer) {
layer = pointerList[action.layer]
} else {
for (let _layer of parent.layers) {
for (let _frame of _layer.frames) {
if (_frame.idx == frame.idx) {
layer = _layer
}
}
}
if (layer==undefined) {
layer = parent.activeLayer
}
}
for (let shapeIdx of action.shapes) { for (let shapeIdx of action.shapes) {
let shape = pointerList[shapeIdx]; let shape = pointerList[shapeIdx];
shape.translate(-action.position.x, -action.position.y); shape.translate(-action.position.x, -action.position.y);
@ -2485,7 +2501,7 @@ class Layer extends Widget {
} }
draw(ctx) { draw(ctx) {
super.draw(ctx) // super.draw(ctx)
let frameInfo = this.getFrameValue(this.frameNum); let frameInfo = this.getFrameValue(this.frameNum);
let frame = frameInfo.valueAtN !== undefined ? frameInfo.valueAtN : frameInfo.prev; let frame = frameInfo.valueAtN !== undefined ? frameInfo.valueAtN : frameInfo.prev;
@ -2531,6 +2547,21 @@ class Layer extends Widget {
} }
} }
} }
for (let child of this.children) {
const transform = ctx.getTransform()
ctx.translate(child.x, child.y)
ctx.rotate(child.rotation)
child.draw(ctx)
if (context.selection.includes(child)) {
ctx.lineWidth = 1;
ctx.strokeStyle = "#00ffff";
ctx.beginPath();
let bbox = child.bbox()
ctx.rect(bbox.x.min-child.x, bbox.y.min-child.y, bbox.x.max-bbox.x.min, bbox.y.max-bbox.y.min)
ctx.stroke()
}
ctx.setTransform(transform)
}
if (this.activeShape) { if (this.activeShape) {
this.activeShape.draw(cxt) this.activeShape.draw(cxt)
} }
@ -2541,6 +2572,19 @@ class Layer extends Widget {
} }
} }
} }
bbox() {
let bbox = super.bbox()
const frameInfo = this.getFrameValue(this.frameNum);
const frame = frameInfo.valueAtN
if (!frame) return bbox;
if (frame.shapes.length > 0 && bbox == undefined) {
bbox = structuredClone(frame.shapes[0].boundingBox);
}
for (let shape of frame.shapes) {
growBoundingBox(bbox, shape.boundingBox);
}
return bbox
}
mousedown(x, y) { mousedown(x, y) {
const mouse = {x: x, y: y} const mouse = {x: x, y: y}
switch(mode) { switch(mode) {
@ -2970,19 +3014,20 @@ class BaseShape {
let curves = []; let curves = [];
let start = current.shift(); let start = current.shift();
let { x, y } = start; let { x, y } = start;
let bezier;
for (let curve of current) { for (let curve of current) {
curves.push( bezier = new Bezier(
new Bezier( x,
x, y,
y, curve.x1,
curve.x1, curve.y1,
curve.y1, curve.x2,
curve.x2, curve.y2,
curve.y2, curve.x,
curve.x, curve.y,
curve.y, )
), bezier.color = lerpColor(this.strokeStyle, shape2.strokeStyle)
); curves.push(bezier);
x = curve.x; x = curve.x;
y = curve.y; y = curve.y;
} }
@ -3615,15 +3660,15 @@ class GraphicsObject extends Widget {
} }
bbox() { bbox() {
let bbox; let bbox;
for (let layer of this.layers) { // for (let layer of this.layers) {
let frame = layer.getFrame(this.currentFrameNum); // let frame = layer.getFrame(this.currentFrameNum);
if (frame.shapes.length > 0 && bbox == undefined) { // if (frame.shapes.length > 0 && bbox == undefined) {
bbox = structuredClone(frame.shapes[0].boundingBox); // bbox = structuredClone(frame.shapes[0].boundingBox);
} // }
for (let shape of frame.shapes) { // for (let shape of frame.shapes) {
growBoundingBox(bbox, shape.boundingBox); // growBoundingBox(bbox, shape.boundingBox);
} // }
} // }
if (this.children.length > 0) { if (this.children.length > 0) {
if (!bbox) { if (!bbox) {
bbox = structuredClone(this.children[0].bbox()); bbox = structuredClone(this.children[0].bbox());
@ -3891,11 +3936,15 @@ class GraphicsObject extends Widget {
} }
super.handleMouseEvent(eventType, x, y) super.handleMouseEvent(eventType, x, y)
} }
addObject(object, x = 0, y = 0, frame = undefined) { addObject(object, x = 0, y = 0, frame = undefined, layer=undefined) {
if (frame == undefined) { if (frame == undefined) {
frame = this.currentFrame; frame = this.currentFrame;
} }
if (layer==undefined) {
layer = this.activeLayer
}
// this.children.push(object); // this.children.push(object);
layer.children.push(object)
object.parent = this; object.parent = this;
object.x = x; object.x = x;
object.y = y; object.y = y;
@ -4999,11 +5048,11 @@ function stage() {
if (!context.dragging) { if (!context.dragging) {
// Have to iterate in reverse order to grab the frontmost object when two overlap // Have to iterate in reverse order to grab the frontmost object when two overlap
for ( for (
let i = context.activeObject.children.length - 1; let i = context.activeObject.activeLayer.children.length - 1;
i >= 0; i >= 0;
i-- i--
) { ) {
child = context.activeObject.children[i]; child = context.activeObject.activeLayer.children[i];
if (!(child.idx in context.activeObject.currentFrame.keys)) if (!(child.idx in context.activeObject.currentFrame.keys))
continue; continue;
// let bbox = child.bbox() // let bbox = child.bbox()
@ -5464,7 +5513,7 @@ function stage() {
context.selectionRect.y2 = mouse.y; context.selectionRect.y2 = mouse.y;
context.selection = []; context.selection = [];
context.shapeselection = []; context.shapeselection = [];
for (let child of context.activeObject.children) { for (let child of context.activeObject.activeLayer.children) {
if (hitTest(regionToBbox(context.selectionRect), child)) { if (hitTest(regionToBbox(context.selectionRect), child)) {
context.selection.push(child); context.selection.push(child);
} }
@ -5601,8 +5650,8 @@ function stage() {
mouse = context.activeObject.transformMouse(mouse); mouse = context.activeObject.transformMouse(mouse);
modeswitcher: switch (mode) { modeswitcher: switch (mode) {
case "select": case "select":
for (let i = context.activeObject.children.length - 1; i >= 0; i--) { for (let i = context.activeObject.activeLayer.children.length - 1; i >= 0; i--) {
let child = context.activeObject.children[i]; let child = context.activeObject.activeLayer.children[i];
if (!(child.idx in context.activeObject.currentFrame.keys)) continue; if (!(child.idx in context.activeObject.currentFrame.keys)) continue;
if (hitTest(mouse, child)) { if (hitTest(mouse, child)) {
context.objectStack.push(child); context.objectStack.push(child);

View File

@ -1,10 +1,19 @@
import { clamp, drawCheckerboardBackground, hslToRgb, hsvToRgb, rgbToHex } from "./utils.js" import { clamp, drawCheckerboardBackground, hslToRgb, hsvToRgb, rgbToHex } from "./utils.js"
function growBoundingBox(bboxa, bboxb) {
bboxa.x.min = Math.min(bboxa.x.min, bboxb.x.min);
bboxa.y.min = Math.min(bboxa.y.min, bboxb.y.min);
bboxa.x.max = Math.max(bboxa.x.max, bboxb.x.max);
bboxa.y.max = Math.max(bboxa.y.max, bboxb.y.max);
}
class Widget { class Widget {
constructor(x, y) { constructor(x, y) {
this._globalEvents = new Set() this._globalEvents = new Set()
this.x = x this.x = x
this.y = y this.y = y
this.scale_x = 1
this.scale_y = 1
this.rotation = 0 this.rotation = 0
this.children = [] this.children = []
} }
@ -47,6 +56,27 @@ class Widget {
} }
return false return false
} }
bbox() {
let bbox;
if (this.children.length > 0) {
if (!bbox) {
bbox = structuredClone(this.children[0].bbox());
}
for (let child of this.children) {
growBoundingBox(bbox, child.bbox());
}
}
if (bbox == undefined) {
bbox = { x: { min: 0, max: 0 }, y: { min: 0, max: 0 } };
}
bbox.x.max *= this.scale_x;
bbox.y.max *= this.scale_y;
bbox.x.min += this.x;
bbox.x.max += this.x;
bbox.y.min += this.y;
bbox.y.max += this.y;
return bbox;
}
draw(ctx) { draw(ctx) {
for (let child of this.children) { for (let child of this.children) {
const transform = ctx.getTransform() const transform = ctx.getTransform()
@ -57,7 +87,6 @@ class Widget {
} }
} }
} }
class HueSelectionBar extends Widget { class HueSelectionBar extends Widget {
constructor(width, height, x, y, colorCvs) { constructor(width, height, x, y, colorCvs) {
super(x, y) super(x, y)