-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlayer.js
123 lines (104 loc) · 3.58 KB
/
layer.js
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"use strict";
class Layer
{
constructor(area)
{
this.area = area;
this.img = document.createElement('canvas');
this.img.width = 1;
this.img.height = 1;
this.img.classList.add('layer');
this._x = this._y = 0;
}
get visible( ) { return this.img.style.display != 'none'; }
set visible(v) { this.img.style.display = v ? '' : 'none'; }
get opacity( ) { return this.img.style.opacity || '1'; }
set opacity(v) { this.img.style.opacity = v; }
get blendMode( ) { return this.img.style.mixBlendMode; }
set blendMode(v) { this.img.style.mixBlendMode = v; }
get x( ) { return this._x; }
get y( ) { return this._y; }
get w( ) { return this.img.width; }
get h( ) { return this.img.height; }
set x(x) { this.move(x, this._y); }
set y(y) { this.move(this._x, y); }
set w(w) { this.crop(this._x, this._y, w, this.h); }
set h(h) { this.crop(this._x, this._y, this.w, h); }
restyle(active, zIndex)
{
if (active)
this.img.classList.add('active');
else
this.img.classList.remove('active');
this.img.style.zIndex = zIndex;
this.img.style.left = this.x + 'em';
this.img.style.top = this.y + 'em';
this.img.style.width = this.w + 'em';
this.img.style.height = this.h + 'em';
}
move(x, y)
{
this._x = x;
this._y = y;
this.area.onLayerRedraw(this);
}
crop(x, y, w, h)
{
const img = this.img.getContext('2d').getImageData(0, 0, this.w, this.h);
this.img.width = w;
this.img.height = h;
this.img.getContext('2d').putImageData(img, this._x - x, this._y - y);
this.move(x, y);
}
resize(w, h)
{
const data = this.img.getContext('2d').getImageData(0, 0, this.w, this.h);
const copy = document.createElement('canvas');
copy.width = this.w;
copy.height = this.h;
copy.getContext('2d').putImageData(data, 0, 0);
this.img.width = w;
this.img.height = h;
this.img.getContext('2d').drawImage(copy, 0, 0, w, h);
this.area.onLayerRedraw(this);
}
get state()
{
return {
x: this.x, y: this.y, w: this.w, h: this.h,
data: this.img.getContext('2d').getImageData(0, 0, this.w, this.h),
blendMode: this.blendMode, opacity: this.opacity, visible: this.visible
};
}
set state(state)
{
this._x = state.x;
this._y = state.y;
if (state.blendMode !== undefined) this.blendMode = state.blendMode;
if (state.opacity !== undefined) this.opacity = state.opacity;
if (state.visible !== undefined) this.visible = state.visible;
if (typeof state.data !== 'string') {
this.img.width = state.w;
this.img.height = state.h;
this.img.getContext('2d').putImageData(state.data, 0, 0);
return this.area.onLayerRedraw(this);
}
const img = new Image();
img.onload = () => {
this.img.width = img.width;
this.img.height = img.height;
this.img.getContext('2d').drawImage(img, 0, 0);
this.area.onLayerRedraw(this);
};
img.src = state.data;
}
drawOnto(ctx)
{
if (!this.visible) return;
ctx.save();
ctx.globalAlpha = parseFloat(this.opacity);
ctx.globalCompositeOperation = !this.blendMode ? 'source-over' : this.blendMode;
ctx.drawImage(this.img, this.x, this.y);
ctx.restore();
}
}