-
Notifications
You must be signed in to change notification settings - Fork 0
/
canvas-drawer-advanced.ts
99 lines (85 loc) · 3.09 KB
/
canvas-drawer-advanced.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { Origin } from "../enums";
import { XYWH } from "../types";
import { CanvasDrawer } from "./canvas-drawer";
import { CanvasManager } from "./canvas-manager";
import { getXYWHFrom } from "./canvas-misc-utilts";
import { CanvasShadowConfig } from "./types/canvas-shadow-config";
export interface ObjectOptions {
opacity?: number;
shadow?: CanvasShadowConfig;
}
export interface StrokeOptions extends ObjectOptions {
width?: number;
strokeColor?: string;
lineDash?: number[];
lineCap?: CanvasLineCap;
joinType?: CanvasLineJoin;
}
export interface FillOptions extends ObjectOptions {
fillColor?: string;
fillImage?: HTMLImageElement;
}
export interface RenderOptions extends ObjectOptions {
fill?: FillOptions;
stroke?: StrokeOptions;
}
export class CanvasDrawerAdvanced {
private readonly drawer = new CanvasDrawer(this.context);
public constructor(private readonly context: CanvasRenderingContext2D) {
}
public renderRect(rawLocation: XYWH, options: RenderOptions, origin = Origin.TL): void {
const location = getXYWHFrom(rawLocation, {x: rawLocation.w, y: rawLocation.h}, origin);
this.prepareShadow(options.shadow);
this.prepareOpacity(options.opacity);
if (options.fill) {
this.prepareShadow(options.fill.shadow);
this.prepareOpacity(options.fill.opacity);
if (options.fill.fillImage) {
this.drawer.drawImage(options.fill.fillImage, location.x, location.y, location.w, location.h);
}
if (options.fill.fillColor) {
this.drawer.fillRect(location.x, location.y, location.w, location.h, options.fill.fillColor);
}
}
if (options.stroke) {
this.prepareShadow(options.stroke.shadow);
this.prepareOpacity(options.stroke.opacity);
this.prepareDashed(options.stroke.lineDash);
if (options.stroke.joinType) {
this.context.lineJoin = options.stroke.joinType;
}
if (options.stroke.lineCap) {
this.context.lineCap = options.stroke.lineCap;
}
const width = options.stroke.width ?? NaN;
if (!isNaN(width)) {
this.context.lineWidth = width;
}
if (options.stroke.strokeColor) {
this.drawer.fillRect(location.x, location.y, location.w, location.h, options.stroke.strokeColor);
}
}
}
private prepareShadow(shadow?: CanvasShadowConfig): void {
if (!shadow) {
return;
}
CanvasManager.setShadow(
this.context,
shadow.x ?? 0,
shadow.y ?? 0,
shadow.color ?? "black",
shadow.blur ?? 5,
);
}
private prepareDashed(dashes?: number[]): void {
if (Array.isArray(dashes)) {
CanvasManager.setLineDash(this.context, ...dashes);
}
}
private prepareOpacity(opacity?: number): void {
if (!isNaN(opacity ?? NaN)) {
this.context.globalAlpha = opacity as number;
}
}
}