animation and frame controls
parent
1574fd0f6b
commit
94bbbaaf3f
|
@ -1,4 +1,4 @@
|
||||||
//I display the canvas and am clickable
|
// I display the canvas and am clickable
|
||||||
export class CanvasHandler {
|
export class CanvasHandler {
|
||||||
private currentImageDiv: HTMLElement;
|
private currentImageDiv: HTMLElement;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
45
app/page.ts
45
app/page.ts
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue