Skip to content

Commit f3bb781

Browse files
authored
Merge pull request #800 from jonobr1/792-object-signatures
792 Object Signatures
2 parents 9880614 + 8c8637a commit f3bb781

File tree

12 files changed

+4198
-3450
lines changed

12 files changed

+4198
-3450
lines changed

build/two.js

Lines changed: 1526 additions & 1506 deletions
Large diffs are not rendered by default.

build/two.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/two.module.js

Lines changed: 1651 additions & 1631 deletions
Large diffs are not rendered by default.

src/effects/image-sequence.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export class ImageSequence extends Rectangle {
123123
constructor(paths, ox, oy, frameRate) {
124124
super(ox, oy, 0, 0);
125125

126+
this._renderer.type = 'image-sequence';
127+
126128
for (let prop in proto) {
127129
Object.defineProperty(this, prop, proto[prop]);
128130
}
@@ -314,6 +316,7 @@ export class ImageSequence extends Rectangle {
314316
*/
315317
toObject() {
316318
const object = super.toObject.call(this);
319+
object.renderer.type = 'image-sequence';
317320
object.textures = this.textures.map(function (texture) {
318321
return texture.toObject();
319322
});
@@ -338,15 +341,15 @@ export class ImageSequence extends Rectangle {
338341
dispose() {
339342
// Call parent dispose to preserve renderer type and unbind events
340343
super.dispose();
341-
344+
342345
// Stop animation if playing
343346
if (this._playing) {
344347
this._playing = false;
345348
}
346-
349+
347350
// Clear animation callbacks
348351
this._onLastFrame = null;
349-
352+
350353
// Unbind textures collection events
351354
if (this.textures && typeof this.textures.unbind === 'function') {
352355
try {
@@ -355,7 +358,7 @@ export class ImageSequence extends Rectangle {
355358
// Ignore unbind errors for incomplete Collection objects
356359
}
357360
}
358-
361+
359362
// Dispose individual textures (more thorough than unbind)
360363
if (this.textures) {
361364
for (let i = 0; i < this.textures.length; i++) {
@@ -367,7 +370,7 @@ export class ImageSequence extends Rectangle {
367370
}
368371
}
369372
}
370-
373+
371374
return this;
372375
}
373376

src/effects/image.js

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export class Image extends Rectangle {
4747
constructor(path, ox, oy, width, height, mode) {
4848
super(ox, oy, width || 1, height || 1);
4949

50+
this._renderer.type = 'image';
51+
5052
for (let prop in proto) {
5153
Object.defineProperty(this, prop, proto[prop]);
5254
}
@@ -72,34 +74,21 @@ export class Image extends Rectangle {
7274
}
7375

7476
/**
75-
* @name Two.Image.fill
76-
* @property {String} - Scale image to fill the bounds while preserving aspect ratio.
77-
*/
78-
static fill = 'fill';
79-
80-
/**
81-
* @name Two.Image.fit
82-
* @property {String} - Scale image to fit within bounds while preserving aspect ratio.
83-
*/
84-
static fit = 'fit';
85-
86-
/**
87-
* @name Two.Image.crop
88-
* @property {String} - Scale image to fill bounds while preserving aspect ratio, cropping excess.
89-
*/
90-
static crop = 'crop';
91-
92-
/**
93-
* @name Two.Image.tile
94-
* @property {String} - Repeat image at original size to fill the bounds.
95-
*/
96-
static tile = 'tile';
97-
98-
/**
99-
* @name Two.Image.stretch
100-
* @property {String} - Stretch image to fill dimensions, ignoring aspect ratio.
77+
* @name Two.Image.Modes
78+
* @property {Object} mode - Different mode types to render an image inspired by Figma.
79+
* @property {String} mode.fill - Scale image to fill the bounds while preserving aspect ratio.
80+
* @property {String} mode.fit - Scale image to fit within bounds while preserving aspect ratio.
81+
* @property {String} mode.crop - Scale image to fill bounds while preserving aspect ratio, cropping excess.
82+
* @property {String} mode.tile - Repeat image at original size to fill the bounds.
83+
* @property {String} mode.stretch - Stretch image to fill dimensions, ignoring aspect ratio.
10184
*/
102-
static stretch = 'stretch';
85+
static Modes = {
86+
fill: 'fill',
87+
fit: 'fit',
88+
crop: 'crop',
89+
tile: 'tile',
90+
stretch: 'stretch',
91+
};
10392

10493
/**
10594
* @name Two.Image.Properties
@@ -175,6 +164,7 @@ export class Image extends Rectangle {
175164
*/
176165
toObject() {
177166
const object = super.toObject.call(this);
167+
object.renderer.type = 'image';
178168
object.texture = this.texture.toObject();
179169
object.mode = this.mode;
180170
return object;
@@ -231,7 +221,7 @@ export class Image extends Rectangle {
231221

232222
// Apply scaling based on mode
233223
switch (this._mode) {
234-
case Image.fill: {
224+
case Image.Modes.fill: {
235225
// Fill within bounds while preserving aspect ratio
236226
const scale = Math.max(scaleX, scaleY);
237227
effect.scale = scale;
@@ -241,7 +231,7 @@ export class Image extends Rectangle {
241231
break;
242232
}
243233

244-
case Image.fit: {
234+
case Image.Modes.fit: {
245235
// Fit within bounds while preserving aspect ratio
246236
const scale = Math.min(scaleX, scaleY);
247237
effect.scale = scale; // TODO: For SVG this works `new Vector(scaleX, scaleY);`
@@ -251,21 +241,21 @@ export class Image extends Rectangle {
251241
break;
252242
}
253243

254-
case Image.crop: {
244+
case Image.Modes.crop: {
255245
// Intentionally left blank to allow
256246
// external developer to control
257247
break;
258248
}
259249

260-
case Image.tile: {
250+
case Image.Modes.tile: {
261251
// Repeat image and align it correctly
262252
effect.offset.x = (iw - rw) / 2;
263253
effect.offset.y = (ih - rh) / 2;
264254
effect.repeat = 'repeat';
265255
break;
266256
}
267257

268-
case Image.stretch:
258+
case Image.Modes.stretch:
269259
default: {
270260
// Stretch the image texture to whatever the dimensions of the rect are
271261
effect.scale = new Vector(scaleX, scaleY);

src/effects/sprite.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ export class Sprite extends Rectangle {
151151
constructor(path, ox, oy, cols, rows, frameRate) {
152152
super(ox, oy, 0, 0);
153153

154+
this._renderer.type = 'sprite';
155+
154156
for (let prop in proto) {
155157
Object.defineProperty(this, prop, proto[prop]);
156158
}
@@ -351,6 +353,7 @@ export class Sprite extends Rectangle {
351353
*/
352354
toObject() {
353355
const object = super.toObject.call(this);
356+
object.renderer.type = 'sprite';
354357
object.texture = this.texture.toObject();
355358
object.columns = this.columns;
356359
object.rows = this.rows;
@@ -375,25 +378,25 @@ export class Sprite extends Rectangle {
375378
dispose() {
376379
// Call parent dispose for inherited cleanup (vertices, fill/stroke effects)
377380
super.dispose();
378-
381+
379382
// Stop animation if playing
380383
if (this._playing) {
381384
this._playing = false;
382385
}
383-
386+
384387
// Clear animation callbacks
385388
this._onLastFrame = null;
386-
389+
387390
// Reset timing properties
388391
this._startTime = 0;
389-
392+
390393
// Dispose texture (more thorough than unbind)
391394
if (this._texture && typeof this._texture.dispose === 'function') {
392395
this._texture.dispose();
393396
} else if (this._texture && typeof this._texture.unbind === 'function') {
394397
this._texture.unbind();
395398
}
396-
399+
397400
return this;
398401
}
399402

src/group.js

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { RoundedRectangle } from './shapes/rounded-rectangle.js';
1515
import { Star } from './shapes/star.js';
1616
import { Text } from './text.js';
1717
import { Element } from './element.js';
18+
import { ImageSequence } from './effects/image-sequence.js';
19+
import { Sprite } from './effects/sprite.js';
1820

1921
// Constants
2022

@@ -317,8 +319,18 @@ export class Group extends Shape {
317319
return ArcSegment.fromObject(child);
318320
case 'circle':
319321
return Circle.fromObject(child);
322+
case 'element':
323+
return Element.fromObject(child);
320324
case 'ellipse':
321325
return Ellipse.fromObject(child);
326+
case 'group':
327+
return Group.fromObject(child);
328+
case 'image':
329+
return Image.fromObject(child);
330+
case 'image-sequence':
331+
return ImageSequence.fromObject(child);
332+
case 'path':
333+
return Path.fromObject(child);
322334
case 'points':
323335
return Points.fromObject(child);
324336
case 'polygon':
@@ -327,18 +339,14 @@ export class Group extends Shape {
327339
return Rectangle.fromObject(child);
328340
case 'rounded-rectangle':
329341
return RoundedRectangle.fromObject(child);
342+
case 'shape':
343+
return Shape.fromObject(child);
344+
case 'sprite':
345+
return Sprite.fromObject(child);
330346
case 'star':
331347
return Star.fromObject(child);
332-
case 'path':
333-
return Path.fromObject(child);
334348
case 'text':
335349
return Text.fromObject(child);
336-
case 'group':
337-
return Group.fromObject(child);
338-
case 'shape':
339-
return Shape.fromObject(child);
340-
case 'element':
341-
return Element.fromObject(child);
342350
}
343351
}
344352
// Commonly null for empty set
@@ -347,9 +355,24 @@ export class Group extends Shape {
347355
}
348356
}
349357

358+
/**
359+
* @name Two.Group#copy
360+
* @function
361+
* @param {Two.Group} [group] - The reference {@link Two.Group}
362+
* @returns {Two.Group}
363+
* @description Copy the properties of one {@link Two.Group} onto another.
364+
*/
350365
copy(group) {
351366
super.copy.call(this, group);
352-
console.warn('Two.Group.copy is not supported yet.');
367+
console.warn(
368+
'Two.js: attempting to copy group. Two.Group.children copying not supported.'
369+
);
370+
for (let i = 0; i < Group.Properties.length; i++) {
371+
const k = Group.Properties[i];
372+
if (k in group) {
373+
this[k] = group[k];
374+
}
375+
}
353376
return this;
354377
}
355378

@@ -434,7 +457,7 @@ export class Group extends Shape {
434457
dispose() {
435458
// Call parent dispose to preserve renderer type and unbind events
436459
super.dispose();
437-
460+
438461
// Recursively dispose all children
439462
if (this.children) {
440463
for (let i = 0; i < this.children.length; i++) {
@@ -444,7 +467,7 @@ export class Group extends Shape {
444467
}
445468
}
446469
}
447-
470+
448471
// Unbind children collection events
449472
if (this.children && typeof this.children.unbind === 'function') {
450473
try {
@@ -453,7 +476,7 @@ export class Group extends Shape {
453476
// Ignore unbind errors for incomplete Collection objects
454477
}
455478
}
456-
479+
457480
return this;
458481
}
459482

0 commit comments

Comments
 (0)