forked from arianne/stendhal
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Dedicated class for manipulating images before they are displayed
- Loading branch information
1 parent
85d6cff
commit c482f6d
Showing
3 changed files
with
149 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/*************************************************************************** | ||
* Copyright © 2024 - Faiumoni e. V. * | ||
*************************************************************************** | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU Affero General Public License as * | ||
* published by the Free Software Foundation; either version 3 of the * | ||
* License, or (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
|
||
/** | ||
* Hidden canvas for manipulating images before they are displayed. | ||
*/ | ||
export class DrawingStage { | ||
|
||
private canvas: HTMLCanvasElement; | ||
|
||
/** Singleton instance. */ | ||
private static instance: DrawingStage; | ||
|
||
|
||
/** | ||
* Retrieves the singleton instance. | ||
*/ | ||
public static get(): DrawingStage { | ||
if (!DrawingStage.instance) { | ||
DrawingStage.instance = new DrawingStage(); | ||
} | ||
return DrawingStage.instance; | ||
} | ||
|
||
/** | ||
* Hidden singleton constructor. | ||
*/ | ||
private constructor() { | ||
this.canvas = document.getElementById("drawing-stage")! as HTMLCanvasElement; | ||
// initialize with smallest possible dimensions | ||
this.clear(); | ||
} | ||
|
||
/** | ||
* Retreives the 2D drawing context of the canves. | ||
*/ | ||
private getContext(): CanvasRenderingContext2D { | ||
return this.canvas.getContext("2d")! as CanvasRenderingContext2D; | ||
} | ||
|
||
/** | ||
* Clears image data from canvas and sets size to minimum possible dimensions. | ||
*/ | ||
public clear() { | ||
this.getContext().clearRect(0, 0, this.canvas.width, this.canvas.height); | ||
this.canvas.width = 0; | ||
this.canvas.height = 0; | ||
} | ||
|
||
/** | ||
* Sets canvas dimensions. | ||
*/ | ||
private setSize(width: number, height: number) { | ||
this.canvas.width = width; | ||
this.canvas.height = height; | ||
} | ||
|
||
/** | ||
* Compares canvas dimensions against image and adjusts if necessary. | ||
*/ | ||
private checkSize(image: HTMLImageElement) { | ||
if (this.canvas.width < image.width || this.canvas.height < image.height) { | ||
this.setSize(image.width, image.height); | ||
} | ||
} | ||
|
||
/** | ||
* Draws an image on the canvas. | ||
* | ||
* @param image | ||
* Image to be drawn. | ||
* @param clear | ||
* If `true` erases current image data before drawing. | ||
*/ | ||
public drawImage(image: HTMLImageElement, clear=true) { | ||
if (clear) { | ||
this.clear(); | ||
} | ||
this.checkSize(image); | ||
this.getContext().drawImage(image, 0, 0); | ||
} | ||
|
||
/** | ||
* Draws a rotated image on the canvas. | ||
* | ||
* NOTE: currently only supports accurate rotation on square image in 90 degree increments | ||
* | ||
* @param image | ||
* Image to be drawn. | ||
* @param angle | ||
* Desired angle of image rotation. | ||
* @param clear | ||
* If `true` erases current image data before drawing. | ||
*/ | ||
public drawImageRotated(image: HTMLImageElement, angle: number, clear=true) { | ||
if (clear) { | ||
this.clear(); | ||
} | ||
this.checkSize(image); | ||
const ctx = this.getContext(); | ||
ctx.translate(this.canvas.width / 2, this.canvas.height / 2); | ||
ctx.rotate(angle * Math.PI / 180); | ||
ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); | ||
// NOTE: do we need to set canvas size again in case of non-square image? | ||
ctx.drawImage(image, 0, 0); | ||
} | ||
|
||
/** | ||
* Converts canvas data to data URL. | ||
* | ||
* @return | ||
* String representation of image data. | ||
*/ | ||
public toDataURL(): string { | ||
return this.canvas.toDataURL("image/png"); | ||
} | ||
|
||
/** | ||
* Converts canvas to PNG image. | ||
* | ||
* @return | ||
* New image. | ||
*/ | ||
public toImage(): HTMLImageElement { | ||
const image = new Image(); | ||
image.src = this.canvas.toDataURL("image/png"); | ||
return image; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters