graphico 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas.js +100 -85
- package/package.json +1 -1
- package/types/canvas.d.ts +16 -23
package/dist/canvas.js
CHANGED
|
@@ -12,6 +12,10 @@ var Canvas = /** @class */ (function () {
|
|
|
12
12
|
function Canvas(options) {
|
|
13
13
|
if (options === void 0) { options = {}; }
|
|
14
14
|
var _this = this;
|
|
15
|
+
/**
|
|
16
|
+
* Can be used to render 2D graphics onto the canvas
|
|
17
|
+
*/
|
|
18
|
+
this.graphics = [];
|
|
15
19
|
/**
|
|
16
20
|
* Contains a list of current keys pressed
|
|
17
21
|
*/
|
|
@@ -36,34 +40,48 @@ var Canvas = /** @class */ (function () {
|
|
|
36
40
|
* The last frame's high resolution timestamp
|
|
37
41
|
*/
|
|
38
42
|
this.lastFrame = 0;
|
|
43
|
+
/**
|
|
44
|
+
* Determine whether the client is focused or not
|
|
45
|
+
*/
|
|
46
|
+
this.focused = false;
|
|
39
47
|
this.config = Canvas.setDefaults(options, Canvas.defaults);
|
|
40
48
|
this.width = this.config.width;
|
|
41
49
|
this.height = this.config.height;
|
|
42
|
-
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
// Create the container <div> element and set properties
|
|
51
|
+
var container = document.createElement('div');
|
|
52
|
+
container.tabIndex = 1; // For element focus
|
|
53
|
+
container.style.outline = 'none';
|
|
54
|
+
container.style.width = "".concat(this.config.width * this.config.scale, "px");
|
|
55
|
+
container.style.height = "".concat(this.config.height * this.config.scale, "px");
|
|
56
|
+
container.style.border = "".concat(this.config.scale, "px solid ").concat(this.config.border);
|
|
57
|
+
container.style.background = this.config.background;
|
|
58
|
+
container.style.cursor = this.config.showMouse ? 'default' : 'none';
|
|
59
|
+
container.style.position = 'relative';
|
|
60
|
+
this.config.parent.appendChild(container);
|
|
61
|
+
// Create canvas layers
|
|
62
|
+
for (var i = 0; i < this.config.numLayers; i++) {
|
|
63
|
+
var canvas = document.createElement('canvas');
|
|
64
|
+
var graphics = canvas.getContext('2d');
|
|
65
|
+
if (graphics) {
|
|
66
|
+
this.graphics.push(graphics);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw new Error('Could not initialize canvas graphics.');
|
|
70
|
+
}
|
|
71
|
+
// Set properties for canvas
|
|
72
|
+
canvas.style.imageRendering = 'pixelated';
|
|
73
|
+
canvas.style.boxSizing = 'border-box';
|
|
74
|
+
canvas.width = this.config.width;
|
|
75
|
+
canvas.height = this.config.height;
|
|
76
|
+
canvas.style.width = '100%';
|
|
77
|
+
canvas.style.height = '100%';
|
|
78
|
+
canvas.style.position = 'absolute';
|
|
79
|
+
graphics.imageSmoothingEnabled = false;
|
|
80
|
+
container.appendChild(canvas);
|
|
49
81
|
}
|
|
50
|
-
// Set static properties
|
|
51
|
-
this.config.parent.appendChild(canvas);
|
|
52
|
-
canvas.tabIndex = 1; // For element focus
|
|
53
|
-
canvas.style.outline = 'none';
|
|
54
|
-
canvas.style.imageRendering = 'pixelated';
|
|
55
|
-
graphics.imageSmoothingEnabled = false;
|
|
56
|
-
// Set custom properties
|
|
57
|
-
canvas.width = this.config.width;
|
|
58
|
-
canvas.height = this.config.height;
|
|
59
|
-
canvas.style.width = "".concat(this.config.width * this.config.scale, "px");
|
|
60
|
-
canvas.style.height = "".concat(this.config.height * this.config.scale, "px");
|
|
61
|
-
canvas.style.background = this.config.background.toString();
|
|
62
|
-
canvas.style.border = "".concat(this.config.scale, "px solid ").concat(this.config.border);
|
|
63
|
-
canvas.style.cursor = this.config.showMouse ? 'default' : 'none';
|
|
64
82
|
// Event listeners
|
|
65
|
-
|
|
66
|
-
if (!_this.
|
|
83
|
+
container.addEventListener('mousemove', function (e) {
|
|
84
|
+
if (!_this.focused) {
|
|
67
85
|
return;
|
|
68
86
|
}
|
|
69
87
|
_this.mouseX = (e.offsetX / _this.config.scale) | 0;
|
|
@@ -71,8 +89,8 @@ var Canvas = /** @class */ (function () {
|
|
|
71
89
|
_this.log(e.type, _this.mouseX, _this.mouseY);
|
|
72
90
|
_this.config.mousemove(_this.mouseX, _this.mouseY);
|
|
73
91
|
});
|
|
74
|
-
|
|
75
|
-
if (!_this.
|
|
92
|
+
container.addEventListener('keydown', function (e) {
|
|
93
|
+
if (!_this.focused) {
|
|
76
94
|
return;
|
|
77
95
|
}
|
|
78
96
|
e.preventDefault();
|
|
@@ -83,8 +101,8 @@ var Canvas = /** @class */ (function () {
|
|
|
83
101
|
_this.config.keydown(key);
|
|
84
102
|
}
|
|
85
103
|
});
|
|
86
|
-
|
|
87
|
-
if (!_this.
|
|
104
|
+
container.addEventListener('keyup', function (e) {
|
|
105
|
+
if (!_this.focused) {
|
|
88
106
|
return;
|
|
89
107
|
}
|
|
90
108
|
var key = e.key.toLowerCase();
|
|
@@ -95,8 +113,8 @@ var Canvas = /** @class */ (function () {
|
|
|
95
113
|
_this.config.keyup(key);
|
|
96
114
|
}
|
|
97
115
|
});
|
|
98
|
-
|
|
99
|
-
if (!_this.
|
|
116
|
+
container.addEventListener('mousedown', function (e) {
|
|
117
|
+
if (!_this.focused) {
|
|
100
118
|
return;
|
|
101
119
|
}
|
|
102
120
|
var button = e.button;
|
|
@@ -106,8 +124,8 @@ var Canvas = /** @class */ (function () {
|
|
|
106
124
|
_this.config.mousedown(button);
|
|
107
125
|
}
|
|
108
126
|
});
|
|
109
|
-
|
|
110
|
-
if (!_this.
|
|
127
|
+
container.addEventListener('mouseup', function (e) {
|
|
128
|
+
if (!_this.focused) {
|
|
111
129
|
return;
|
|
112
130
|
}
|
|
113
131
|
var button = e.button;
|
|
@@ -118,30 +136,26 @@ var Canvas = /** @class */ (function () {
|
|
|
118
136
|
_this.config.mouseup(button);
|
|
119
137
|
}
|
|
120
138
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
_this.
|
|
139
|
+
container.addEventListener('focusin', function (e) {
|
|
140
|
+
_this.focused = true;
|
|
141
|
+
container.style.borderColor = _this.config.border;
|
|
142
|
+
_this.log(e.type, _this.focused);
|
|
124
143
|
_this.animation = requestAnimationFrame(function (time) { return _this.startAnimate(time); });
|
|
125
144
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
_this.
|
|
145
|
+
container.addEventListener('focusout', function (e) {
|
|
146
|
+
_this.focused = false;
|
|
147
|
+
container.style.borderColor = _this.config.borderBlur;
|
|
148
|
+
_this.log(e.type, _this.focused);
|
|
129
149
|
cancelAnimationFrame(_this.animation);
|
|
130
150
|
});
|
|
131
151
|
window.addEventListener('blur', function (e) {
|
|
132
152
|
_this.log(e.type);
|
|
133
153
|
cancelAnimationFrame(_this.animation);
|
|
134
154
|
});
|
|
135
|
-
|
|
155
|
+
container.addEventListener('contextmenu', function (e) { return e.preventDefault(); });
|
|
136
156
|
// Focus on the canvas
|
|
137
|
-
|
|
157
|
+
container.focus();
|
|
138
158
|
}
|
|
139
|
-
/**
|
|
140
|
-
* Determine if the canvas is currently focused.
|
|
141
|
-
*/
|
|
142
|
-
Canvas.prototype.isFocused = function () {
|
|
143
|
-
return this.graphics.canvas === document.activeElement;
|
|
144
|
-
};
|
|
145
159
|
/**
|
|
146
160
|
* Start the animation.
|
|
147
161
|
*/
|
|
@@ -156,16 +170,11 @@ var Canvas = /** @class */ (function () {
|
|
|
156
170
|
*/
|
|
157
171
|
Canvas.prototype.animate = function (time) {
|
|
158
172
|
var _this = this;
|
|
159
|
-
var _a;
|
|
160
173
|
var currentFrame = time;
|
|
161
174
|
var dt = currentFrame - this.lastFrame;
|
|
162
175
|
this.lastFrame = currentFrame;
|
|
163
176
|
this.log('animate', dt, currentFrame);
|
|
164
|
-
|
|
165
|
-
for (var _i = 0, drawables_1 = drawables; _i < drawables_1.length; _i++) {
|
|
166
|
-
var drawable = drawables_1[_i];
|
|
167
|
-
this.draw(drawable);
|
|
168
|
-
}
|
|
177
|
+
this.config.loop(dt);
|
|
169
178
|
this.animation = requestAnimationFrame(function (time) { return _this.animate(time); });
|
|
170
179
|
};
|
|
171
180
|
/**
|
|
@@ -191,55 +200,60 @@ var Canvas = /** @class */ (function () {
|
|
|
191
200
|
Canvas.prototype.getMousePosition = function () {
|
|
192
201
|
return [this.mouseX, this.mouseY];
|
|
193
202
|
};
|
|
194
|
-
/**
|
|
195
|
-
* Get the color of the selected pixel.
|
|
196
|
-
* @param x The pixel's x-coordinate
|
|
197
|
-
* @param y The pixel's y-coordinate
|
|
198
|
-
* @returns `[red, green, blue, alpha]`
|
|
199
|
-
*/
|
|
200
|
-
Canvas.prototype.getPixel = function (x, y) {
|
|
201
|
-
var data = this.graphics.getImageData(x, y, 1, 1).data;
|
|
202
|
-
console.log(this.graphics.getImageData(x, y, 2, 2));
|
|
203
|
-
;
|
|
204
|
-
return [data[0], data[1], data[2], data[3]];
|
|
205
|
-
};
|
|
206
|
-
/**
|
|
207
|
-
* Set the color of the selected pixel.
|
|
208
|
-
* @param x The pixel's x-coordinate
|
|
209
|
-
* @param y The pixel's y-coordinate
|
|
210
|
-
* @param color `[red, green, blue, alpha]`
|
|
211
|
-
*/
|
|
212
|
-
Canvas.prototype.setPixel = function (x, y, color) {
|
|
213
|
-
var data = this.graphics.getImageData(x, y, 1, 1);
|
|
214
|
-
data.data[0] = color[0];
|
|
215
|
-
data.data[1] = color[1];
|
|
216
|
-
data.data[2] = color[2];
|
|
217
|
-
data.data[3] = color[3];
|
|
218
|
-
console.log(data);
|
|
219
|
-
this.graphics.putImageData(data, x, y);
|
|
220
|
-
};
|
|
221
203
|
/**
|
|
222
204
|
* Take a screenshot of the canvas contents and save to a .png file.
|
|
205
|
+
* @param name The file name of the screenshot
|
|
223
206
|
*/
|
|
224
|
-
Canvas.prototype.screenshot = function () {
|
|
225
|
-
|
|
207
|
+
Canvas.prototype.screenshot = function (name) {
|
|
208
|
+
if (name === void 0) { name = 'screenshot'; }
|
|
209
|
+
// Create an offscreen canvas
|
|
210
|
+
var screen = new Canvas({
|
|
211
|
+
parent: document.createElement('div'),
|
|
212
|
+
height: this.config.height,
|
|
213
|
+
width: this.config.width,
|
|
214
|
+
scale: this.config.scale,
|
|
215
|
+
});
|
|
216
|
+
// Draw the background and each layer
|
|
217
|
+
screen.graphics[0].fillStyle = this.config.background;
|
|
218
|
+
screen.graphics[0].fillRect(0, 0, screen.width, screen.height);
|
|
219
|
+
for (var _i = 0, _a = this.graphics; _i < _a.length; _i++) {
|
|
220
|
+
var graphic = _a[_i];
|
|
221
|
+
screen.graphics[0].drawImage(graphic.canvas, 0, 0);
|
|
222
|
+
}
|
|
223
|
+
// Generate a data URL and set it as the download parameter for <a>
|
|
224
|
+
var dataURL = screen.graphics[0].canvas.toDataURL();
|
|
226
225
|
var downloadLink = document.createElement('a');
|
|
227
226
|
downloadLink.setAttribute('href', dataURL);
|
|
228
|
-
downloadLink.setAttribute('download',
|
|
227
|
+
downloadLink.setAttribute('download', name);
|
|
229
228
|
downloadLink.click();
|
|
229
|
+
// Remove all keys and mouse buttons down because we lose focus
|
|
230
|
+
this.keys.splice(0);
|
|
231
|
+
this.mouseButtons.splice(0);
|
|
230
232
|
};
|
|
231
233
|
/**
|
|
232
234
|
* Draw an object onto the canvas.
|
|
233
235
|
* @param drawable Any drawable object
|
|
236
|
+
* @param layer The zero-indexed layer to draw to
|
|
234
237
|
*/
|
|
235
|
-
Canvas.prototype.draw = function (drawable) {
|
|
236
|
-
|
|
238
|
+
Canvas.prototype.draw = function (drawable, layer) {
|
|
239
|
+
if (layer === void 0) { layer = 0; }
|
|
240
|
+
drawable.draw(this.graphics[layer]);
|
|
237
241
|
};
|
|
238
242
|
/**
|
|
239
243
|
* Completely clears the canvas.
|
|
244
|
+
* @param layer The zero-indexed layer to clear, if unset, will clear all layers
|
|
240
245
|
*/
|
|
241
|
-
Canvas.prototype.clear = function () {
|
|
242
|
-
|
|
246
|
+
Canvas.prototype.clear = function (layer) {
|
|
247
|
+
if (layer === void 0) { layer = -1; }
|
|
248
|
+
if (layer < 0) {
|
|
249
|
+
for (var _i = 0, _a = this.graphics; _i < _a.length; _i++) {
|
|
250
|
+
var graphic = _a[_i];
|
|
251
|
+
graphic.clearRect(0, 0, this.config.width, this.config.height);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.graphics[layer].clearRect(0, 0, this.config.width, this.config.height);
|
|
256
|
+
}
|
|
243
257
|
};
|
|
244
258
|
/**
|
|
245
259
|
* Log a message to the debug console.
|
|
@@ -278,6 +292,7 @@ var Canvas = /** @class */ (function () {
|
|
|
278
292
|
border: 'transparent',
|
|
279
293
|
borderBlur: 'transparent',
|
|
280
294
|
showMouse: true,
|
|
295
|
+
numLayers: 1,
|
|
281
296
|
keydown: function () { return; },
|
|
282
297
|
keyup: function () { return; },
|
|
283
298
|
mousemove: function () { return; },
|
package/package.json
CHANGED
package/types/canvas.d.ts
CHANGED
|
@@ -46,15 +46,15 @@ export declare class Canvas {
|
|
|
46
46
|
* The last frame's high resolution timestamp
|
|
47
47
|
*/
|
|
48
48
|
private lastFrame;
|
|
49
|
+
/**
|
|
50
|
+
* Determine whether the client is focused or not
|
|
51
|
+
*/
|
|
52
|
+
private focused;
|
|
49
53
|
/**
|
|
50
54
|
* Create a new canvas with the provided options
|
|
51
55
|
* @param options Configuration options
|
|
52
56
|
*/
|
|
53
57
|
constructor(options?: Partial<Options>);
|
|
54
|
-
/**
|
|
55
|
-
* Determine if the canvas is currently focused.
|
|
56
|
-
*/
|
|
57
|
-
private isFocused;
|
|
58
58
|
/**
|
|
59
59
|
* Start the animation.
|
|
60
60
|
*/
|
|
@@ -80,33 +80,22 @@ export declare class Canvas {
|
|
|
80
80
|
* @returns Cursor position as `[x, y]`
|
|
81
81
|
*/
|
|
82
82
|
getMousePosition(): [number, number];
|
|
83
|
-
/**
|
|
84
|
-
* Get the color of the selected pixel.
|
|
85
|
-
* @param x The pixel's x-coordinate
|
|
86
|
-
* @param y The pixel's y-coordinate
|
|
87
|
-
* @returns `[red, green, blue, alpha]`
|
|
88
|
-
*/
|
|
89
|
-
getPixel(x: number, y: number): [number, number, number, number];
|
|
90
|
-
/**
|
|
91
|
-
* Set the color of the selected pixel.
|
|
92
|
-
* @param x The pixel's x-coordinate
|
|
93
|
-
* @param y The pixel's y-coordinate
|
|
94
|
-
* @param color `[red, green, blue, alpha]`
|
|
95
|
-
*/
|
|
96
|
-
setPixel(x: number, y: number, color: [number, number, number, number]): void;
|
|
97
83
|
/**
|
|
98
84
|
* Take a screenshot of the canvas contents and save to a .png file.
|
|
85
|
+
* @param name The file name of the screenshot
|
|
99
86
|
*/
|
|
100
|
-
screenshot(): void;
|
|
87
|
+
screenshot(name?: string): void;
|
|
101
88
|
/**
|
|
102
89
|
* Draw an object onto the canvas.
|
|
103
90
|
* @param drawable Any drawable object
|
|
91
|
+
* @param layer The zero-indexed layer to draw to
|
|
104
92
|
*/
|
|
105
|
-
draw(drawable: Drawable): void;
|
|
93
|
+
draw(drawable: Drawable, layer?: number): void;
|
|
106
94
|
/**
|
|
107
95
|
* Completely clears the canvas.
|
|
96
|
+
* @param layer The zero-indexed layer to clear, if unset, will clear all layers
|
|
108
97
|
*/
|
|
109
|
-
clear(): void;
|
|
98
|
+
clear(layer?: number): void;
|
|
110
99
|
/**
|
|
111
100
|
* Log a message to the debug console.
|
|
112
101
|
*/
|
|
@@ -156,6 +145,10 @@ export interface Options {
|
|
|
156
145
|
* Optionally show or hide the mouse when hovering over the canvas
|
|
157
146
|
*/
|
|
158
147
|
readonly showMouse: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* The number of layers in this canvas
|
|
150
|
+
*/
|
|
151
|
+
readonly numLayers: number;
|
|
159
152
|
/**
|
|
160
153
|
* Event listener for when a key is pressed
|
|
161
154
|
* @param key The key that was pressed
|
|
@@ -185,9 +178,9 @@ export interface Options {
|
|
|
185
178
|
/**
|
|
186
179
|
* Event listener for a the main animation loop
|
|
187
180
|
* @param dt The number of milliseconds in between frames
|
|
188
|
-
* @returns An array of `Drawable` to render, or void
|
|
181
|
+
* @returns An array of `Drawable` to render on layer 0, or void
|
|
189
182
|
*/
|
|
190
|
-
readonly loop: (dt: number) =>
|
|
183
|
+
readonly loop: (dt: number) => void;
|
|
191
184
|
}
|
|
192
185
|
/**
|
|
193
186
|
* Represents an object that can be drawn on the canvas.
|