Animation Data, Canvas Image limiting
parent
607fe1e9ee
commit
07baa6d8bd
|
@ -0,0 +1,11 @@
|
||||||
|
import { IFrame } from './IFrame';
|
||||||
|
import { IPin } from './IPin';
|
||||||
|
|
||||||
|
export interface IAnimationData {
|
||||||
|
frameRate: number;
|
||||||
|
originX: number;
|
||||||
|
originY: number;
|
||||||
|
loop: boolean;
|
||||||
|
frames: IFrame[];
|
||||||
|
pins: IPin[];
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { IFramePinData } from './IFramePinData';
|
||||||
|
|
||||||
|
export interface IFrame {
|
||||||
|
filename: string;
|
||||||
|
pinData: IFramePinData[];
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
export interface IFramePinData {
|
||||||
|
id: number;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface IPin {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
//I display the canvas and am clickable
|
||||||
|
export class CanvasHandler {
|
||||||
|
private currentImageDiv: HTMLElement;
|
||||||
|
|
||||||
|
constructor(currentImageDiv: HTMLElement) {
|
||||||
|
this.currentImageDiv = currentImageDiv;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,31 @@
|
||||||
export class FileHandler {
|
export class FileHandler {
|
||||||
public static ProcessImages(fileList: FileList): string[] {
|
public static ProcessImages = (fileList: FileList): Promise<string[]> => {
|
||||||
const filenames: string[] = [];
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const filenames: string[] = [];
|
||||||
|
|
||||||
// files is a FileList of File objects. List some properties.
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
for (let i = 0; i < fileList.length; i++) {
|
const file = fileList[i];
|
||||||
const f = fileList[i];
|
const filename = await FileHandler.ProcessImage(file);
|
||||||
|
|
||||||
|
filenames.push(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(filenames);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
private static ProcessImage = (file: File): Promise<string> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.onload = ((theFile) => {
|
reader.onload = (event: any) => {
|
||||||
return (e: any) => {
|
resolve(event.target!.result);
|
||||||
filenames.push(e.target.result);
|
};
|
||||||
};
|
|
||||||
})(f);
|
reader.onerror = reject;
|
||||||
|
|
||||||
// Read in the image file as a data URL.
|
// Read in the image file as a data URL.
|
||||||
reader.readAsDataURL(f);
|
reader.readAsDataURL(file);
|
||||||
}
|
});
|
||||||
|
};
|
||||||
return filenames;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
export class FrameHandler {
|
export class FrameHandler {
|
||||||
|
private frameNumberDiv: HTMLElement;
|
||||||
|
|
||||||
private filenames: string[] = [];
|
private filenames: string[] = [];
|
||||||
private currentFrame: number = 0;
|
private currentFrame: number = 0;
|
||||||
private currentImageDiv: HTMLElement;
|
private currentImageDiv: HTMLElement;
|
||||||
|
|
||||||
constructor(currentImageDiv: HTMLElement) {
|
constructor(currentImageDiv: HTMLElement, frameNumberDiv: HTMLElement) {
|
||||||
this.currentImageDiv = currentImageDiv;
|
this.currentImageDiv = currentImageDiv;
|
||||||
|
this.frameNumberDiv = frameNumberDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GetCurrentFrame(): number {
|
||||||
|
return this.currentFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadFrames(filenames: string[]) {
|
public loadFrames(filenames: string[]) {
|
||||||
this.filenames = filenames;
|
this.filenames = filenames;
|
||||||
this.currentFrame = 0;
|
this.currentFrame = 0;
|
||||||
|
this.SetCurrentImageDiv();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AdvanceFrames(amount: number) {
|
public AdvanceFrames(amount: number) {
|
||||||
|
@ -23,7 +31,15 @@ export class FrameHandler {
|
||||||
|
|
||||||
public GoToFrame(frame: number) {
|
public GoToFrame(frame: number) {
|
||||||
this.currentFrame = frame;
|
this.currentFrame = frame;
|
||||||
|
this.SetCurrentImageDiv();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SetCurrentImageDiv() {
|
||||||
this.currentImageDiv.innerHTML = `<img src="${this.filenames[this.currentFrame]}"></img>`;
|
this.currentImageDiv.innerHTML = `<img src="${this.filenames[this.currentFrame]}"></img>`;
|
||||||
console.log('current frame = ', this.currentFrame);
|
if (this.filenames.length === 0) {
|
||||||
|
this.frameNumberDiv.innerText = 'No images uploaded yet. Drag images onto the page to upload them';
|
||||||
|
} else {
|
||||||
|
this.frameNumberDiv.innerText = 'Current Frame: ' + this.currentFrame.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
52
app/page.ts
52
app/page.ts
|
@ -1,5 +1,8 @@
|
||||||
|
import { CanvasHandler } from './canvas_handler';
|
||||||
import { FileHandler } from './file_handler';
|
import { FileHandler } from './file_handler';
|
||||||
import { FrameHandler } from './frame_handler';
|
import { FrameHandler } from './frame_handler';
|
||||||
|
import { IAnimationData } from './Interfaces/IAnimationData';
|
||||||
|
import { IFrame } from './Interfaces/IFrame';
|
||||||
|
|
||||||
export class Page {
|
export class Page {
|
||||||
private static handleDragOver(evt: DragEvent) {
|
private static handleDragOver(evt: DragEvent) {
|
||||||
|
@ -10,14 +13,34 @@ export class Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private filenames: string[] = [];
|
private frameHandler: FrameHandler;
|
||||||
|
private canvasHandler: CanvasHandler;
|
||||||
|
private animationData: IAnimationData;
|
||||||
|
|
||||||
public Load() {
|
public Load() {
|
||||||
// const fileHandler = new FileHandler('dropZone', 'output', this.filenames);
|
// defining blank slate animation data
|
||||||
const frameHandler = new FrameHandler(document.getElementById('currentImage') as HTMLElement);
|
this.animationData = {
|
||||||
|
pins: [],
|
||||||
|
originX: 0,
|
||||||
|
originY: 0,
|
||||||
|
frameRate: 30,
|
||||||
|
loop: true,
|
||||||
|
frames: [
|
||||||
|
{
|
||||||
|
filename: '',
|
||||||
|
pinData: []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
this.canvasHandler = new CanvasHandler(document.getElementById('currentImage') as HTMLElement);
|
||||||
|
|
||||||
|
this.frameHandler = new FrameHandler(
|
||||||
|
document.getElementById('currentImage') as HTMLElement,
|
||||||
|
document.getElementById('frameNumber') as HTMLElement
|
||||||
|
);
|
||||||
|
|
||||||
const dropZone = document.getElementById('dropZone') as HTMLElement;
|
const dropZone = document.getElementById('dropZone') as HTMLElement;
|
||||||
const output = document.getElementById('output') as HTMLElement;
|
|
||||||
|
|
||||||
dropZone.addEventListener('dragover', Page.handleDragOver, false);
|
dropZone.addEventListener('dragover', Page.handleDragOver, false);
|
||||||
dropZone.addEventListener('drop', this.handleFileSelect, false);
|
dropZone.addEventListener('drop', this.handleFileSelect, false);
|
||||||
|
@ -27,14 +50,14 @@ export class Page {
|
||||||
case 39: {
|
case 39: {
|
||||||
// right_arrow
|
// right_arrow
|
||||||
console.log('next frame action');
|
console.log('next frame action');
|
||||||
frameHandler.AdvanceFrames(1);
|
this.frameHandler.AdvanceFrames(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 37: {
|
case 37: {
|
||||||
// left arrow
|
// left arrow
|
||||||
console.log('previous frame action');
|
console.log('previous frame action');
|
||||||
frameHandler.AdvanceFrames(-1);
|
this.frameHandler.AdvanceFrames(-1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,12 +66,23 @@ export class Page {
|
||||||
document.addEventListener('keydown', keyDown);
|
document.addEventListener('keydown', keyDown);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleFileSelect = (event: any) => {
|
private handleFileSelect = async (event: DragEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
FileHandler.ProcessImages(event.target.result);
|
const filenames = await FileHandler.ProcessImages(event.dataTransfer!.files);
|
||||||
|
this.frameHandler.loadFrames(filenames);
|
||||||
|
|
||||||
console.log('files: ' + this.filenames.length);
|
const newFrames: IFrame[] = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < event.dataTransfer!.files.length; i++) {
|
||||||
|
newFrames.push({
|
||||||
|
filename: event.dataTransfer!.files[i].name,
|
||||||
|
pinData: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.animationData.frames = newFrames;
|
||||||
|
console.log(this.animationData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,3 +17,8 @@ main {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#currentImage img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
|
@ -11,17 +11,19 @@
|
||||||
<div id="dropZone">
|
<div id="dropZone">
|
||||||
<div id="output"></div>
|
<div id="output"></div>
|
||||||
|
|
||||||
<div id="thing" class="sub">
|
<div id="instructions" class="sub">
|
||||||
<p>Hi hihihihihihi</p>
|
<p>advance frames with arrow keys</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="frameNumber" class="sub">
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<!-- canvas -->
|
||||||
|
<div id="currentImage">
|
||||||
|
<img alt="Current Image">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- canvas -->
|
|
||||||
<div id="currentImage">
|
|
||||||
<img alt="Current Image">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<script src="bundle.js"></script>
|
<script src="bundle.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue