Skip to content

Commit

Permalink
🐞 metafizzy#65 add Box face property setter
Browse files Browse the repository at this point in the history
fix bug updating Box properties to update faces
  • Loading branch information
desandro committed Jun 13, 2019
1 parent 125bda0 commit 4d913b4
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 62 deletions.
4 changes: 2 additions & 2 deletions js/anchor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ function Anchor( options ) {
}

Anchor.prototype.create = function( options ) {
this.children = [];
// set defaults & options
utils.extend( this, this.constructor.defaults );
this.setOptions( options );
Expand All @@ -35,8 +36,7 @@ Anchor.prototype.create = function( options ) {
// origin
this.origin = new Vector();
this.renderOrigin = new Vector();
// children
this.children = [];

if ( this.addTo ) {
this.addTo.addChild( this );
}
Expand Down
167 changes: 107 additions & 60 deletions js/box.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,87 +24,69 @@ BoxRect.prototype.copyGraph = function() {};

// ----- Box ----- //

var boxDefaults = utils.extend( {
var TAU = utils.TAU;
var faceNames = [
'frontFace',
'rearFace',
'leftFace',
'rightFace',
'topFace',
'bottomFace',
];

var boxDefaults = utils.extend( {}, Shape.defaults );
delete boxDefaults.path;
faceNames.forEach( function( faceName ) {
boxDefaults[ faceName ] = true;
});
utils.extend( boxDefaults, {
width: 1,
height: 1,
depth: 1,
frontFace: true,
rearFace: true,
leftFace: true,
rightFace: true,
topFace: true,
bottomFace: true,
}, Shape.defaults );
// default fill
boxDefaults.fill = true;
delete boxDefaults.path;
fill: true,
});

var Box = Anchor.subclass( boxDefaults );

var TAU = utils.TAU;

Box.prototype.create = function( options ) {
Anchor.prototype.create.call( this, options );
this.updatePath();
// HACK reset fill to trigger face setter
this.fill = this.fill;
};

Box.prototype.updatePath = function() {
this.setFace( 'frontFace', {
width: this.width,
height: this.height,
translate: { z: this.depth/2 },
});
this.setFace( 'rearFace', {
width: this.width,
height: this.height,
translate: { z: -this.depth/2 },
rotate: { y: TAU/2 },
});
this.setFace( 'leftFace', {
width: this.depth,
height: this.height,
translate: { x: -this.width/2 },
rotate: { y: -TAU/4 },
});
this.setFace( 'rightFace', {
width: this.depth,
height: this.height,
translate: { x: this.width/2 },
rotate: { y: TAU/4 },
});
this.setFace( 'topFace', {
width: this.width,
height: this.depth,
translate: { y: -this.height/2 },
rotate: { x: -TAU/4 },
});
this.setFace( 'bottomFace', {
width: this.width,
height: this.depth,
translate: { y: this.height/2 },
rotate: { x: -TAU/4 },
});
// reset all faces to trigger setters
faceNames.forEach( function( faceName ) {
this[ faceName ] = this[ faceName ];
}, this );
};

Box.prototype.setFace = function( faceName, options ) {
var property = this[ faceName ];
faceNames.forEach( function( faceName ) {
var _faceName = '_' + faceName;
Object.defineProperty( Box.prototype, faceName, {
get: function() {
return this[ _faceName ];
},
set: function( value ) {
this[ _faceName ] = value;
this.setFace( faceName, value );
},
});
});

Box.prototype.setFace = function( faceName, value ) {
var rectProperty = faceName + 'Rect';
var rect = this[ rectProperty ];
// remove if false
if ( !property ) {
if ( !value ) {
this.removeChild( rect );
return;
}
// update & add face
utils.extend( options, {
// set color from option, i.e. `front: '#19F'`
color: typeof property == 'string' ? property : this.color,
stroke: this.stroke,
fill: this.fill,
backface: this.backface,
front: this.front,
visible: this.visible,
});
var options = this.getFaceOptions( faceName );
options.color = typeof value == 'string' ? value : this.color;

if ( rect ) {
// update previous
rect.setOptions( options );
Expand All @@ -116,6 +98,71 @@ Box.prototype.setFace = function( faceName, options ) {
this.addChild( rect );
};

Box.prototype.getFaceOptions = function( faceName ) {
return {
frontFace: {
width: this.width,
height: this.height,
translate: { z: this.depth/2 },
},
rearFace: {
width: this.width,
height: this.height,
translate: { z: -this.depth/2 },
rotate: { y: TAU/2 },
},
leftFace: {
width: this.depth,
height: this.height,
translate: { x: -this.width/2 },
rotate: { y: -TAU/4 },
},
rightFace: {
width: this.depth,
height: this.height,
translate: { x: this.width/2 },
rotate: { y: TAU/4 },
},
topFace: {
width: this.width,
height: this.depth,
translate: { y: -this.height/2 },
rotate: { x: -TAU/4 },
},
bottomFace: {
width: this.width,
height: this.depth,
translate: { y: this.height/2 },
rotate: { x: TAU/4 },
},
}[ faceName ];
};

// ----- set face properties ----- //

var childProperties = [ 'color', 'stroke', 'fill', 'backface', 'front',
'visible' ];
childProperties.forEach( function( property ) {
// use proxy property for custom getter & setter
var _prop = '_' + property;
Object.defineProperty( Box.prototype, property, {
get: function() {
return this[ _prop ];
},
set: function( value ) {
this[ _prop ] = value;
faceNames.forEach( function( faceName ) {
var rect = this[ faceName + 'Rect' ];
var isFaceColor = typeof this[ faceName ] == 'string';
var isColorUnderwrite = property == 'color' && isFaceColor;
if ( rect && !isColorUnderwrite ) {
rect[ property ] = value;
}
}, this );
},
});
});

return Box;

}));

0 comments on commit 4d913b4

Please sign in to comment.