animation and frame controls

master
Beau Blyth 2019-09-26 17:45:28 -07:00
parent 1574fd0f6b
commit 94bbbaaf3f
4 changed files with 78 additions and 17 deletions

View File

@ -1,21 +1,21 @@
import { IAnimationData } from './Interfaces/IAnimationData';
export class FrameHandler { export class FrameHandler {
private start: number = 0;
private frameNumberDiv: HTMLElement; private frameNumberDiv: HTMLElement;
private animationData: IAnimationData;
private filenames: string[] = []; private filenames: string[] = [];
private currentFrame: number = 0; private currentFrame: number = 0;
private currentImageDiv: HTMLElement; private currentImageDiv: HTMLElement;
private playingAnimation: boolean; private playingAnimation: boolean;
constructor(currentImageDiv: HTMLElement, frameNumberDiv: HTMLElement) { constructor(animationData: IAnimationData, currentImageDiv: HTMLElement, frameNumberDiv: HTMLElement) {
this.animationData = animationData;
this.currentImageDiv = currentImageDiv; this.currentImageDiv = currentImageDiv;
this.frameNumberDiv = frameNumberDiv; this.frameNumberDiv = frameNumberDiv;
setTimeout(this.Update, 1000 / 60); window.requestAnimationFrame(this.windowAnimationUpdate);
}
public Update() {
console.log('updating');
AdvanceFrames(1);
setTimeout(this.Update, 1000 / 60);
} }
public GetCurrentFrame(): number { public GetCurrentFrame(): number {
@ -42,6 +42,14 @@ export class FrameHandler {
this.SetCurrentImageDiv(); this.SetCurrentImageDiv();
} }
public TogglePlayingAnimation() {
this.playingAnimation = !this.playingAnimation;
console.log('playingAnimation = ', this.playingAnimation);
}
public StopPlayingAnimation() {
this.playingAnimation = false;
}
private SetCurrentImageDiv() { private SetCurrentImageDiv() {
this.currentImageDiv.innerHTML = `<img src="${this.filenames[this.currentFrame]}"></img>`; this.currentImageDiv.innerHTML = `<img src="${this.filenames[this.currentFrame]}"></img>`;
if (this.filenames.length === 0) { if (this.filenames.length === 0) {
@ -50,12 +58,20 @@ export class FrameHandler {
} else { } else {
this.frameNumberDiv.className = 'instruction'; this.frameNumberDiv.className = 'instruction';
this.frameNumberDiv.innerText = this.frameNumberDiv.innerText =
'Frame ' + this.currentFrame.toString() + ' / ' + (this.filenames.length - 1).toString(); 'Frame ' + (this.currentFrame + 1).toString() + ' / ' + this.filenames.length.toString();
} }
} }
public TogglePlayingAnimation() { private windowAnimationUpdate = (timestamp: number) => {
this.playingAnimation = !this.playingAnimation; if (this.start === 0) {
console.log('playingAnimation = ', this.playingAnimation); this.start = timestamp;
} }
const progress = timestamp - this.start;
if (this.playingAnimation && progress > 1000 / this.animationData.frameRate) {
this.AdvanceFrames(1);
this.start = 0;
}
window.requestAnimationFrame(this.windowAnimationUpdate);
console.log('timestamp = ' + timestamp);
};
} }

View File

@ -37,6 +37,7 @@ export class Page {
// this.canvasHandler.currentImageDiv.addEventListener('onmousedown', ClickOnCanvas); // this.canvasHandler.currentImageDiv.addEventListener('onmousedown', ClickOnCanvas);
this.frameHandler = new FrameHandler( this.frameHandler = new FrameHandler(
this.animationData,
document.getElementById('currentImage') as HTMLElement, document.getElementById('currentImage') as HTMLElement,
document.getElementById('frameNumber') as HTMLElement document.getElementById('frameNumber') as HTMLElement
); );
@ -48,11 +49,32 @@ export class Page {
const keyDown = (event: KeyboardEvent) => { const keyDown = (event: KeyboardEvent) => {
switch (event.keyCode) { switch (event.keyCode) {
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57: {
// goto frame w 1234567890
if (event.keyCode === 48) {
this.frameHandler.GoToFrame(9);
} else {
this.frameHandler.GoToFrame(event.keyCode - 49);
}
this.frameHandler.StopPlayingAnimation();
break;
}
case 39: case 39:
case 190: { case 190: {
// right_arrow, carrot // right_arrow, carrot
console.log('next frame action'); console.log('next frame action');
this.frameHandler.AdvanceFrames(1); this.frameHandler.AdvanceFrames(1);
this.frameHandler.StopPlayingAnimation();
break; break;
} }
@ -61,17 +83,27 @@ export class Page {
// left arrow, carrot // left arrow, carrot
console.log('previous frame action'); console.log('previous frame action');
this.frameHandler.AdvanceFrames(-1); this.frameHandler.AdvanceFrames(-1);
this.frameHandler.StopPlayingAnimation();
break; break;
} }
case 40: { case 40: {
// down arrow // down arrow
this.frameHandler.GoToFrame(0); this.frameHandler.GoToFrame(0);
this.frameHandler.StopPlayingAnimation();
break;
} }
case 32: { case 32: {
// spacebar // spacebar
this.frameHandler.TogglePlayingAnimation(); this.frameHandler.TogglePlayingAnimation();
break;
}
case 83: {
// s
this.download('.anim', String(this.animationData));
break;
} }
} }
}; };
@ -98,4 +130,17 @@ export class Page {
this.animationData.frames = newFrames; this.animationData.frames = newFrames;
console.log(this.animationData); console.log(this.animationData);
}; };
private download(filename: string, text: string) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
} }

6
dist/index.html vendored
View File

@ -24,10 +24,10 @@
<div id="settings"> <div id="settings">
Origin X: <input type="text" name="originX" value="0" size="2"> Origin X: <input type="text" name="originX" value="0" size="2">
Y: <input type="text" name="originX" value="0" size="2"><br> Y: <input type="text" name="originY" value="0" size="2"><br>
Fps: <input type="text" name="FirstName" value="60"><br> Fps: <input type="text" name="framerate" value="60"><br>
<input type="checkbox" name="looping" > Looping <br> <input type="checkbox" name="looping" > Looping <br>
<button type="button" onclick="alert('saved')">export .anim</button> <button id="saveButton" type="button">export .anim with (S)</button>
</div> </div>
</div> </div>