diff --git a/app/Interfaces/IAnimationData.ts b/app/Interfaces/IAnimationData.ts index fb29901..b91e84d 100644 --- a/app/Interfaces/IAnimationData.ts +++ b/app/Interfaces/IAnimationData.ts @@ -1,5 +1,5 @@ import { IFrame } from './IFrame'; -import { IPin } from './IPin'; +import { IPinDefinition } from './IPinDefinition'; export interface IAnimationData { frameRate: number; @@ -7,5 +7,5 @@ export interface IAnimationData { originY: number | null; loop: boolean; frames: IFrame[]; - pins: IPin[]; + pinDefinitions: IPinDefinition[]; } diff --git a/app/Interfaces/IFrame.ts b/app/Interfaces/IFrame.ts index a2fc666..5eaebc2 100644 --- a/app/Interfaces/IFrame.ts +++ b/app/Interfaces/IFrame.ts @@ -1,6 +1,6 @@ -import { IFramePinData } from './IFramePinData'; +import { IPositionData } from './IPositionData'; export interface IFrame { filename: string; - pinData: IFramePinData; + pinData: IPositionData[]; } diff --git a/app/Interfaces/IFramePinData.ts b/app/Interfaces/IFramePinData.ts deleted file mode 100644 index a2b9431..0000000 --- a/app/Interfaces/IFramePinData.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface IFramePinData { - [id: number]: { - x: number; - y: number; - }; -} diff --git a/app/Interfaces/IPin.ts b/app/Interfaces/IPin.ts deleted file mode 100644 index 738e64c..0000000 --- a/app/Interfaces/IPin.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IPin { - id: number; - name: string; -} diff --git a/app/Interfaces/IPinDefinition.ts b/app/Interfaces/IPinDefinition.ts new file mode 100644 index 0000000..6ac98d6 --- /dev/null +++ b/app/Interfaces/IPinDefinition.ts @@ -0,0 +1,4 @@ +export interface IPinDefinition { + id: number; + name: string; +} diff --git a/app/Interfaces/IPositionData.ts b/app/Interfaces/IPositionData.ts new file mode 100644 index 0000000..b01a663 --- /dev/null +++ b/app/Interfaces/IPositionData.ts @@ -0,0 +1,4 @@ +export interface IPositionData { + x: number; + y: number; +} diff --git a/app/canvas_handler.ts b/app/canvas_handler.ts index 3cbd665..628db56 100644 --- a/app/canvas_handler.ts +++ b/app/canvas_handler.ts @@ -1,5 +1,4 @@ import { IAnimationData } from './Interfaces/IAnimationData'; -import { IFramePinData } from './Interfaces/IFramePinData'; import { IProjectData } from './Interfaces/IProjectData'; // I display the canvas and am clickable @@ -56,13 +55,11 @@ export class CanvasHandler { // get origin in pixels const pixelX: number = Math.floor(offsetX / ratioWidth); const pixelY: number = Math.floor(offsetY / ratioHeight); - // console.log('CLICK X:' + pixelX + ' Y:' + pixelY); - if (this.projectData.currentlySelectedPin === 0) { + if (this.projectData.currentlySelectedPin === -1) { // update animation data this.animationData.originX = pixelX; this.animationData.originY = pixelY; } else { - // console.log('current pin id = ' + this.projectData.currentlySelectedPin); const newPinData = { x: pixelX, y: pixelY diff --git a/app/frame_handler.ts b/app/frame_handler.ts index aadd20a..ba466d4 100644 --- a/app/frame_handler.ts +++ b/app/frame_handler.ts @@ -1,5 +1,4 @@ import { IAnimationData } from './Interfaces/IAnimationData'; -import { IFramePinData } from './Interfaces/IFramePinData'; import { IProjectData } from './Interfaces/IProjectData'; export class FrameHandler { @@ -138,11 +137,10 @@ export class FrameHandler { for (let f = 0; f < this.animationData.frames.length; f++) { // this.frameViewer.children[f].classList.add('warning'); - if (this.animationData.pins !== undefined) { - for (let p = 0; p < this.animationData.pins.length; p++) { - if (this.animationData.pins[p] !== undefined) { - const pinIDtoCheck = this.animationData.pins[p].id; - // console.log('checking frame ' + f + ' for pinID ' + this.animationData.pins[p].name); + if (this.animationData.pinDefinitions !== undefined) { + for (let p = 0; p < this.animationData.pinDefinitions.length; p++) { + if (this.animationData.pinDefinitions[p] !== undefined) { + const pinIDtoCheck = this.animationData.pinDefinitions[p].id; if (this.frameViewer.children[f] !== undefined) { if (this.animationData.frames[f].pinData[pinIDtoCheck] === undefined) { this.frameViewer.children[f].classList.add('warning'); @@ -217,6 +215,5 @@ export class FrameHandler { } this.RefreshImage(); window.requestAnimationFrame(this.windowAnimationUpdate); - // console.log('timestamp = ' + timestamp); }; } diff --git a/app/page.ts b/app/page.ts index 1d8d331..39abed9 100644 --- a/app/page.ts +++ b/app/page.ts @@ -45,18 +45,18 @@ export class Page { frames: [ { filename: '', - pinData: {} + pinData: [] } ], loop: true, originX: -1, originY: -1, - pins: [] + pinDefinitions: [] }; // blank slate canvas data this.projectData = { currentFrame: 0, - currentlySelectedPin: 0, + currentlySelectedPin: -1, height: 0, heightRatio: 0, width: 0, @@ -206,7 +206,7 @@ export class Page { } private ExportData() { - this.pinHandler.UpdateAnimationPinNames(); + this.pinHandler.UpdateAnimationPinDefinitions(); if (this.ProjectHasNeccesaryData()) { const zip = new JSZip(); @@ -263,16 +263,16 @@ export class Page { let passPinData: boolean = true; for (let f = 0; f < this.animationData.frames.length; f++) { const errorOnFrame: boolean = false; - if (this.animationData.pins !== undefined) { - for (let p = 0; p < this.animationData.pins.length; p++) { - if (this.animationData.pins[p] !== undefined) { - const pinIDtoCheck = this.animationData.pins[p].id; + if (this.animationData.pinDefinitions !== undefined) { + for (let p = 0; p < this.animationData.pinDefinitions.length; p++) { + if (this.animationData.pinDefinitions[p] !== undefined) { + const pinIDtoCheck = this.animationData.pinDefinitions[p].id; // console.log('checking frame ' + f + ' for pinID ' + this.animationData.pins[p].name); if (this.animationData.frames[f].pinData[pinIDtoCheck] === undefined) { if (!errorOnFrame) { pinDataErrorString += f + ' :\n'; } - pinDataErrorString += ' Pin: ' + this.animationData.pins[p].name + '\n'; + pinDataErrorString += ' Pin: ' + this.animationData.pinDefinitions[p].name + '\n'; passPinData = false; } } @@ -299,7 +299,6 @@ export class Page { private AddPinButtonPressed = () => { this.pinHandler.AddNewPin(); - this.pinHandler.pins += 1; }; private handleFileSelect = async (event: DragEvent) => { @@ -316,7 +315,7 @@ export class Page { for (let i = 0; i < originalFilenames.length; i++) { newFrames.push({ filename: originalFilenames[i].toString(), - pinData: {} + pinData: [] }); } @@ -336,12 +335,12 @@ export class Page { private ResetProgram = () => { // defining blank slate animation data - this.animationData.pins = []; + this.animationData.pinDefinitions = []; this.animationData.originX = null; this.animationData.originY = null; this.animationData.frameRate = 30; this.animationData.loop = true; - this.animationData.frames = [ { filename: '', pinData: {} } ]; + this.animationData.frames = [ { filename: '', pinData: [] } ]; // blank slate canvas data this.projectData.currentFrame = 0; diff --git a/app/pin_handler.ts b/app/pin_handler.ts index 3ed8797..38be799 100644 --- a/app/pin_handler.ts +++ b/app/pin_handler.ts @@ -1,9 +1,8 @@ import { IAnimationData } from './Interfaces/IAnimationData'; -import { IPin } from './Interfaces/IPin'; +import { IPinDefinition } from './Interfaces/IPinDefinition'; import { IProjectData } from './Interfaces/IProjectData'; export class PinHandler { - public pins: number = 1; private pinSettingsDiv: HTMLElement; private pinContainer: HTMLElement; private allPinContainers: HTMLElement[]; @@ -26,13 +25,12 @@ export class PinHandler { this.originPin = originPin; this.originPin.classList.add('pinButtonContainer'); // add origin click behaviour - this.originPin.id = 'pinID_0'; this.originPin.addEventListener('click', () => { - this.projectData.currentlySelectedPin = 0; + this.projectData.currentlySelectedPin = -1; this.UpdatePinBoxStatus(); }); // put origin into pincontainer array - this.allPinContainers = [ originPin ]; + this.allPinContainers = []; } public UpdatePinBoxStatus = () => { @@ -48,7 +46,6 @@ export class PinHandler { if (this.animationData.frames[f] !== undefined) { if (this.animationData.frames[f].pinData[pinNumber] === undefined) { pinDiv.classList.add('warning'); - // console.log('added warning'); break; } } @@ -57,26 +54,24 @@ export class PinHandler { if (this.animationData.originX === null || this.animationData.originY === null) { this.originPin.classList.add('warning'); } - if (this.projectData.currentlySelectedPin === 0) { + if (this.projectData.currentlySelectedPin === -1) { this.originPin.classList.add('selected'); } }; - public UpdateAnimationPinNames = () => { - const animationPinData: IPin[] = []; - for (let i = 1; i < this.allPinContainers.length; i++) { + public UpdateAnimationPinDefinitions = () => { + const animationPinData: IPinDefinition[] = []; + for (let i = 0; i < this.allPinContainers.length; i++) { const pinName: string = this.GetPinNameFromDiv(this.allPinContainers[i]); - // console.log('new pin name = ' + pinName); if (pinName !== null && pinName !== undefined) { - const newPinData: IPin = { + const newPinData: IPinDefinition = { id: this.GetPinNumberFromID(this.allPinContainers[i].id), name: pinName }; animationPinData.push(newPinData); } } - this.animationData.pins = animationPinData; - // console.log('updated animationPinData to ' + animationPinData); + this.animationData.pinDefinitions = animationPinData; }; public RemoveAllPins = () => { @@ -87,7 +82,7 @@ export class PinHandler { } this.allPinContainers.splice(1, this.allPinContainers.length - 1); this.UpdatePinBoxStatus(); - this.UpdateAnimationPinNames(); + this.UpdateAnimationPinDefinitions(); }; public GetAvailablePins = (): number[] => { @@ -96,7 +91,6 @@ export class PinHandler { const pinID: number = this.GetPinNumberFromID(this.allPinContainers[i].id); availablePins.push(pinID); } - // console.log('available pins are: ' + availablePins); return availablePins; }; @@ -116,19 +110,21 @@ export class PinHandler { const newDiv = document.createElement('div'); this.allPinContainers.push(newDiv); + let newPinIDString = this.animationData.pinDefinitions.length.toString(); + this.pinContainer.appendChild(newDiv); - newDiv.id = 'pinID_' + this.pins.toString(); + newDiv.id = 'pinID_' + newPinIDString; newDiv.className = 'pinButtonContainer'; // text input field for pin name const newNameInput = document.createElement('input'); - newNameInput.id = 'nameInput_' + this.pins.toString(); + newNameInput.id = 'nameInput_' + newPinIDString; newDiv.addEventListener('click', () => { this.SelectPin(newDiv); }); newDiv.appendChild(newNameInput); - newNameInput.value = 'PinName_' + this.pins.toString(); + newNameInput.value = 'PinName_' + newPinIDString; newNameInput.addEventListener('focusout', () => { - this.UpdateAnimationPinNames(); + this.UpdateAnimationPinDefinitions(); }); // button to remove pin const removePinButton = document.createElement('div'); @@ -146,21 +142,21 @@ export class PinHandler { indexToDelete = i; } } - if (indexToDelete !== 0) { + if (indexToDelete !== -1) { this.allPinContainers.splice(indexToDelete, 1); } // remove data associated with that id from all frames this.RemovePinDataForID(idNumber); // remove the div itself newDiv.remove(); - this.UpdateAnimationPinNames(); + //this.UpdateAnimationPinDefinitions(); //reset to origin this.SelectOriginPin(); }); // break - this.UpdateAnimationPinNames(); + this.UpdateAnimationPinDefinitions(); this.UpdatePinBoxStatus(); }; @@ -174,29 +170,43 @@ export class PinHandler { private SelectPin = (pinDiv: HTMLElement) => { this.projectData.currentlySelectedPin = this.GetPinNumberFromID(pinDiv.id); - // console.log('selected pin ' + this.projectData.currentlySelectedPin); this.UpdatePinBoxStatus(); - this.UpdateAnimationPinNames(); + this.UpdateAnimationPinDefinitions(); }; private SelectOriginPin = () => { - this.projectData.currentlySelectedPin = 0; + this.projectData.currentlySelectedPin = -1; this.UpdatePinBoxStatus(); }; private RemovePinDataForID = (pinID: number) => { // check for matching id in pin list and remove + let indexToDelete = -1; + let deleted: boolean = false; - for (let i = 0; i < this.animationData.pins.length; i++) { - // console.log('checking if ' + this.animationData.pins[i].id.toString + ' === ' + pinID.toString()); - if (this.animationData.pins[i].id === pinID) { - delete this.animationData.pins[i]; + for (let i = 0; i < this.animationData.pinDefinitions.length; i++) { + if (this.animationData.pinDefinitions[i].id === pinID) { + indexToDelete = i; } - // console.log('deleting pinID ' + pinID); deleted = true; } + if (indexToDelete == -1) { + return; + } + + let removedPinDefinition = this.animationData.pinDefinitions[indexToDelete]; + this.animationData.pinDefinitions.splice(indexToDelete, 1); + for (let i = this.animationData.pinDefinitions.length - 1; i >= 0; i--) { + let pinDefinition = this.animationData.pinDefinitions[i]; + if (pinDefinition.id > removedPinDefinition.id) { + let div = document.getElementById('pinID_' + pinDefinition.id); + div!.id = 'pinID_' + (pinDefinition.id - 1); + pinDefinition.id -= 1; + } + } + if (!deleted) { // console.log('failed to find pinID ' + pinID + ' in list of pins'); } @@ -204,7 +214,8 @@ export class PinHandler { // delete pin data from each frame for (let f = 0; f < this.animationData.frames.length; f++) { if (this.animationData.frames[f].pinData[pinID] !== undefined) { - delete this.animationData.frames[f].pinData[pinID]; + //delete this.animationData.frames[f].pinData[pinID]; + this.animationData.frames[f].pinData.splice(pinID, 1); // console.log('deleting pinID ' + pinID + ' data from frame ' + f); } else { // console.log('tried to delete pinID ' + pinID + ' data from frame ' + f + ' but it doesnt exist'); diff --git a/webpack/dev.config.js b/webpack/dev.config.js index 5669c14..c3f8b12 100644 --- a/webpack/dev.config.js +++ b/webpack/dev.config.js @@ -8,7 +8,7 @@ module.exports = { main: [ './index.ts' ] }, output: { - filename: 'exporter/bundle.js' + filename: 'bundle.js' }, resolve: { // Add `.ts` and `.tsx` as a resolvable extension. @@ -16,7 +16,7 @@ module.exports = { }, plugins: [ new MiniCssExtractPlugin({ - filename: 'exporter/main.css' + filename: 'main.css' }) ], module: {