Make copy-pasted objects editable

This commit is contained in:
Skyler Lehmkuhl 2025-01-03 16:20:46 -05:00
parent 2143655a8d
commit 59c7cedb4d
1 changed files with 98 additions and 45 deletions

View File

@ -505,6 +505,9 @@ let actions = {
); );
} }
shape.update(); shape.update();
console.log(context.activeObject.currentFrame.shapes);
console.log(shape);
updateUI();
}, },
rollback: (action) => { rollback: (action) => {
let shape = pointerList[action.shape]; let shape = pointerList[action.shape];
@ -659,10 +662,12 @@ let actions = {
}, },
}, },
duplicateObject: { duplicateObject: {
create: (object) => { create: (items) => {
redoStack.length = 0; redoStack.length = 0;
let action = { let action = {
object: object.idx, items: items,
object: context.activeObject.idx,
frame: context.activeObject.currentFrame.idx,
uuid: uuidv4(), uuid: uuidv4(),
}; };
undoStack.push({ name: "duplicateObject", action: action }); undoStack.push({ name: "duplicateObject", action: action });
@ -670,16 +675,33 @@ let actions = {
updateMenu(); updateMenu();
}, },
execute: (action) => { execute: (action) => {
// your code here console.log(action);
let object = pointerList[action.object]; const object = pointerList[action.object];
let newObj = object.copy(action.uuid); const frame = pointerList[action.frame];
for (let item of action.items) {
if (item.type == "shape") {
frame.addShape(Shape.fromJSON(item));
} else if (item.type == "GraphicsObject") {
const newObj = GraphicsObject.fromJSON(item);
object.addObject(newObj);
console.log(newObj.idx);
console.log(frame.keys);
}
}
// newObj.idx = action.uuid // newObj.idx = action.uuid
context.activeObject.addObject(newObj); // context.activeObject.addObject(newObj);
updateUI(); updateUI();
}, },
rollback: (action) => { rollback: (action) => {
let object = pointerList[action.uuid]; const object = pointerList[action.object];
context.activeObject.removeChild(object); const frame = pointerList[action.frame];
for (let item of action.items) {
if (item.type == "shape") {
frame.removeShape(pointerList[item.idx]);
} else if (item.type == "GraphicsObject") {
object.removeChild(pointerList[item.idx]);
}
}
updateUI(); updateUI();
}, },
}, },
@ -1074,8 +1096,6 @@ let actions = {
execute: (action) => { execute: (action) => {
let frame = pointerList[action.frame]; let frame = pointerList[action.frame];
frame.keys = structuredClone(action.newState); frame.keys = structuredClone(action.newState);
console.log(structuredClone(frame.keys));
console.log(frame.keys);
updateUI(); updateUI();
}, },
rollback: (action) => { rollback: (action) => {
@ -2014,15 +2034,19 @@ class Frame {
return frame; return frame;
} }
toJSON() { toJSON(randomizeUuid = false) {
const json = {}; const json = {};
json.type = "Frame"; json.type = "Frame";
json.frameType = this.frameType; json.frameType = this.frameType;
json.idx = this.idx; if (randomizeUuid) {
json.idx = uuidv4();
} else {
json.idx = this.idx;
}
json.keys = this.keys; json.keys = this.keys;
json.shapes = []; json.shapes = [];
for (let shape of this.shapes) { for (let shape of this.shapes) {
json.shapes.push(shape.toJSON()); json.shapes.push(shape.toJSON(randomizeUuid));
} }
return json; return json;
} }
@ -2101,18 +2125,23 @@ class Layer {
return layer; return layer;
} }
toJSON() { toJSON(randomizeUuid = false) {
const json = {}; const json = {};
json.type = "Layer"; json.type = "Layer";
json.idx = this.idx; if (randomizeUuid) {
json.idx = uuidv4();
json.name = this.name + " copy";
} else {
json.idx = this.idx;
json.name = this.name;
}
json.children = []; json.children = [];
for (let child of this.children) { for (let child of this.children) {
json.children.push(child.toJSON()); json.children.push(child.toJSON(randomizeUuid));
} }
json.name = this.name;
json.frames = []; json.frames = [];
for (let frame of this.frames) { for (let frame of this.frames) {
json.frames.push(frame.toJSON()); json.frames.push(frame.toJSON(randomizeUuid));
} }
json.visible = this.visible; json.visible = this.visible;
json.audible = this.audible; json.audible = this.audible;
@ -2401,14 +2430,19 @@ class AudioLayer {
audioLayer.audible = json.audible; audioLayer.audible = json.audible;
return audioLayer; return audioLayer;
} }
toJSON() { toJSON(randomizeUuid = false) {
const json = {}; const json = {};
json.type = "AudioLayer"; json.type = "AudioLayer";
// TODO: build json from audiolayer // TODO: build json from audiolayer
json.sounds = {}; json.sounds = {};
json.audible = this.audible; json.audible = this.audible;
json.idx = this.idx; if (randomizeUuid) {
json.name = this.name; json.idx = uuidv4();
json.name = this.name + " copy";
} else {
json.idx = this.idx;
json.name = this.name;
}
return json; return json;
} }
copy(idx) { copy(idx) {
@ -2614,7 +2648,7 @@ class Shape extends BaseShape {
} }
return shape; return shape;
} }
toJSON() { toJSON(randomizeUuid = false) {
const json = {}; const json = {};
json.type = "Shape"; json.type = "Shape";
json.startx = this.startx; json.startx = this.startx;
@ -2625,17 +2659,21 @@ class Shape extends BaseShape {
json.lineWidth = this.lineWidth; json.lineWidth = this.lineWidth;
json.filled = this.filled; json.filled = this.filled;
json.stroked = this.stroked; json.stroked = this.stroked;
json.idx = this.idx; if (randomizeUuid) {
json.idx = uuidv4();
} else {
json.idx = this.idx;
}
json.shapeId = this.shapeId; json.shapeId = this.shapeId;
json.curves = []; json.curves = [];
for (let curve of this.curves) { for (let curve of this.curves) {
json.curves.push(curve.toJSON()); json.curves.push(curve.toJSON(randomizeUuid));
} }
json.regions = []; json.regions = [];
for (let region of this.regions) { for (let region of this.regions) {
const curves = []; const curves = [];
for (let curve of region.curves) { for (let curve of region.curves) {
curves.push(curve.toJSON()); curves.push(curve.toJSON(randomizeUuid));
} }
json.regions.push({ json.regions.push({
idx: region.idx, idx: region.idx,
@ -3021,7 +3059,7 @@ class GraphicsObject {
} }
return graphicsObject; return graphicsObject;
} }
toJSON() { toJSON(randomizeUuid = false) {
const json = {}; const json = {};
json.type = "GraphicsObject"; json.type = "GraphicsObject";
json.x = this.x; json.x = this.x;
@ -3029,17 +3067,22 @@ class GraphicsObject {
json.rotation = this.rotation; json.rotation = this.rotation;
json.scale_x = this.scale_x; json.scale_x = this.scale_x;
json.scale_y = this.scale_y; json.scale_y = this.scale_y;
json.idx = this.idx; if (randomizeUuid) {
json.name = this.name; json.idx = uuidv4();
json.name = this.name + " copy";
} else {
json.idx = this.idx;
json.name = this.name;
}
json.currentFrameNum = this.currentFrameNum; json.currentFrameNum = this.currentFrameNum;
json.currentLayer = this.currentLayer; json.currentLayer = this.currentLayer;
json.layers = []; json.layers = [];
for (let layer of this.layers) { for (let layer of this.layers) {
json.layers.push(layer.toJSON()); json.layers.push(layer.toJSON(randomizeUuid));
} }
json.audioLayers = []; json.audioLayers = [];
for (let audioLayer of this.audioLayers) { for (let audioLayer of this.audioLayers) {
json.audioLayers.push(audioLayer.toJSON()); json.audioLayers.push(audioLayer.toJSON(randomizeUuid));
} }
return json; return json;
} }
@ -3629,7 +3672,7 @@ async function _save(path) {
console.log(action.name); console.log(action.name);
} }
const fileData = { const fileData = {
version: "1.6", version: "1.7",
width: config.fileWidth, width: config.fileWidth,
height: config.fileHeight, height: config.fileHeight,
fps: config.framerate, fps: config.framerate,
@ -3756,6 +3799,19 @@ async function _open(path, returnJson = false) {
} }
} }
} }
if (file.version <= "1.6") {
// Fix copy-paste
if (action.name == "duplicateObject") {
const obj = pointerList[action.action.object];
const objJson = obj.toJSON(true);
objJson.idx =
action.action.uuid.slice(0, 8) +
action.action.object.slice(8);
action.action.items = [objJson];
action.action.object = "root";
action.action.frame = root.currentFrame.idx;
}
}
await actions[action.name].execute(action.action); await actions[action.name].execute(action.action);
undoStack.push(action); undoStack.push(action);
@ -3952,22 +4008,23 @@ async function quit() {
function copy() { function copy() {
clipboard = []; clipboard = [];
for (let object of context.selection) { for (let object of context.selection) {
clipboard.push(object); clipboard.push(object.toJSON(true));
} }
for (let shape of context.shapeselection) { for (let shape of context.shapeselection) {
clipboard.push(shape); clipboard.push(shape.toJSON(true));
} }
console.log(clipboard); console.log(clipboard);
} }
function paste() { function paste() {
for (let item of clipboard) { // for (let item of clipboard) {
if (item instanceof GraphicsObject) { // if (item instanceof GraphicsObject) {
console.log(item); // console.log(item);
// context.activeObject.addObject(item.copy()) // // context.activeObject.addObject(item.copy())
actions.duplicateObject.create(item); // actions.duplicateObject.create(item);
} // }
} // }
actions.duplicateObject.create(clipboard);
updateUI(); updateUI();
} }
@ -5401,6 +5458,7 @@ function timeline() {
mouse.y -= gutterHeight; mouse.y -= gutterHeight;
timeline_cvs.clicked_frame = Math.floor(mouse.x / frameWidth); timeline_cvs.clicked_frame = Math.floor(mouse.x / frameWidth);
context.activeObject.setFrameNum(timeline_cvs.clicked_frame); context.activeObject.setFrameNum(timeline_cvs.clicked_frame);
console.log(context.activeObject.currentFrame.shapes[0].idx);
const layerIdx = Math.floor(mouse.y / layerHeight); const layerIdx = Math.floor(mouse.y / layerHeight);
if (layerIdx < context.activeObject.layers.length && layerIdx >= 0) { if (layerIdx < context.activeObject.layers.length && layerIdx >= 0) {
const layer = const layer =
@ -5523,7 +5581,6 @@ function timeline() {
} }
} }
updateLayers(); updateLayers();
console.log(mouse);
}); });
timeline_cvs.addEventListener("mouseup", (e) => { timeline_cvs.addEventListener("mouseup", (e) => {
let mouse = getMousePos(timeline_cvs, e); let mouse = getMousePos(timeline_cvs, e);
@ -5544,7 +5601,6 @@ function timeline() {
updateLayers(); updateLayers();
updateMenu(); updateMenu();
} }
console.log(mouse);
}); });
timeline_cvs.addEventListener("mousemove", (e) => { timeline_cvs.addEventListener("mousemove", (e) => {
let mouse = getMousePos(timeline_cvs, e); let mouse = getMousePos(timeline_cvs, e);
@ -5818,7 +5874,6 @@ function splitPane(div, percent, horiz, newPane = undefined) {
} }
div.setAttribute("lb-percent", percent); // TODO: better attribute name div.setAttribute("lb-percent", percent); // TODO: better attribute name
div.addEventListener("mousedown", function (event) { div.addEventListener("mousedown", function (event) {
console.log("click");
// Check if the clicked element is the parent itself and not a child element // Check if the clicked element is the parent itself and not a child element
if (event.target === event.currentTarget) { if (event.target === event.currentTarget) {
if (event.button === 0) { if (event.button === 0) {
@ -5972,7 +6027,6 @@ function splitPane(div, percent, horiz, newPane = undefined) {
} }
}); });
div.addEventListener("mouseup", (event) => { div.addEventListener("mouseup", (event) => {
console.log("mouseup");
event.currentTarget.setAttribute("dragging", false); event.currentTarget.setAttribute("dragging", false);
// event.currentTarget.style.userSelect = 'auto'; // event.currentTarget.style.userSelect = 'auto';
}); });
@ -6320,7 +6374,6 @@ function renderLayers() {
ctx.globalCompositeOperation = "difference"; ctx.globalCompositeOperation = "difference";
for (let frame of context.selectedFrames) { for (let frame of context.selectedFrames) {
ctx.fillStyle = "grey"; ctx.fillStyle = "grey";
console.log(frame.frameNum);
ctx.fillRect( ctx.fillRect(
frame.frameNum * frameWidth, frame.frameNum * frameWidth,
frame.layer * layerHeight, frame.layer * layerHeight,