flattened shadow object into shadowColor, shadowBlur, shadowOpacity, and shadowOffset attrs

This commit is contained in:
Eric Rowell 2012-12-31 00:45:38 -08:00
parent 9cd0df651c
commit 83bf1740a6
8 changed files with 225 additions and 228 deletions

View File

@ -145,7 +145,7 @@
*/
fillStroke: function(shape) {
this._fill(shape);
this._stroke(shape, shape.getShadow() && shape.getFill());
this._stroke(shape, shape.hasShadow() && shape.getFill());
},
/**
* apply shadow
@ -215,11 +215,11 @@
Kinetic.SceneCanvas.prototype = {
_fill: function(shape, skipShadow) {
var context = this.context, fill = shape.getFill(), fillType = shape._getFillType(fill), shadow = shape.getShadow();
var context = this.context, fill = shape.getFill(), fillType = shape._getFillType(fill);
if(fill) {
context.save();
if(!skipShadow && shadow) {
if(!skipShadow && shape.hasShadow()) {
this._applyShadow(shape);
}
@ -281,13 +281,13 @@
context.restore();
if(!skipShadow && shadow && shadow.opacity) {
if(!skipShadow && shape.hasShadow()) {
this._fill(shape, true);
}
}
},
_stroke: function(shape, skipShadow) {
var context = this.context, stroke = shape.getStroke(), strokeWidth = shape.getStrokeWidth(), shadow = shape.getShadow(), dashArray = shape.getDashArray();
var context = this.context, stroke = shape.getStroke(), strokeWidth = shape.getStrokeWidth(), dashArray = shape.getDashArray();
if(stroke || strokeWidth) {
context.save();
this._applyLineCap(shape);
@ -299,7 +299,7 @@
Kinetic.Global.warn('Could not apply dash array because your browser does not support it.');
}
}
if(!skipShadow && shadow) {
if(!skipShadow && shape.hasShadow()) {
this._applyShadow(shape);
}
context.lineWidth = strokeWidth || 2;
@ -307,25 +307,25 @@
context.stroke(context);
context.restore();
if(!skipShadow && shadow && shadow.opacity) {
if(!skipShadow && shape.hasShadow()) {
this._stroke(shape, true);
}
}
},
_applyShadow: function(shape) {
var context = this.context, shadow = shape.getShadow();
if(shadow) {
var context = this.context;
if(shape.hasShadow()) {
var aa = shape.getAbsoluteOpacity();
// defaults
var color = shadow.color || 'black';
var blur = shadow.blur || 5;
var offset = shadow.offset || {
var color = shape.getShadowColor() || 'black';
var blur = shape.getShadowBlur() || 5;
var offset = shape.getShadowOffset() || {
x: 0,
y: 0
};
if(shadow.opacity) {
context.globalAlpha = shadow.opacity * aa;
if(shape.getShadowOpacity()) {
context.globalAlpha = shape.getShadowOpacity() * aa;
}
context.shadowColor = color;
context.shadowBlur = blur;

View File

@ -25,13 +25,12 @@
* @param {Number} [config.strokeWidth] stroke width
* @param {String} [config.lineJoin] line join can be miter, round, or bevel. The default
* is miter
* @param {Object} [config.shadow] shadow object
* @param {String} [config.shadow.color]
* @param {Number} [config.shadow.blur]
* @param {Obect} [config.shadow.blur.offset]
* @param {Number} [config.shadow.blur.offset.x]
* @param {Number} [config.shadow.blur.offset.y]
* @param {Number} [config.shadow.opacity] shadow opacity. Can be any real number
* @param {String} [config.shadowColor]
* @param {Number} [config.shadowBlur]
* @param {Obect} [config.shadowOffset]
* @param {Number} [config.shadowOffset.x]
* @param {Number} [config.shadowOffset.y]
* @param {Number} [config.shadowOpacity] shadow opacity. Can be any real number
* between 0 and 1
* @param {Array} [config.dashArray]
* @param {Number} [config.width]
@ -78,6 +77,14 @@
getCanvas: function() {
return this.getLayer().getCanvas();
},
/**
* returns whether or not a shadow will be rendered
* @name hasShadow
* @methodOf Kinetic.Shape.prototype
*/
hasShadow: function() {
return !!(this.getShadowColor() || this.getShadowBlur() || this.getShadowOffset());
},
_getFillType: function(fill) {
var type = Kinetic.Type;
if(!fill) {
@ -100,21 +107,20 @@
}
},
/**
* set shadow object
* @name setShadow
* set shadow offset
* @name setShadowOffset
* @methodOf Kinetic.Shape.prototype
* @param {Object} config
* @param {String} config.color
* @param {Number} config.blur
* @param {Array|Object|Number} config.offset
* @param {Number} config.opacity
* @param {Number|Array|Object} offset
*/
setShadow: function(config) {
var type = Kinetic.Type;
if(config.offset !== undefined) {
config.offset = type._getXY(config.offset);
setShadowOffset: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
if(pos.x === undefined) {
pos.x = this.getShadowOffset().x;
}
this.setAttr('shadow', type._merge(config, this.getShadow()));
if(pos.y === undefined) {
pos.y = this.getShadowOffset().y;
}
this.setAttr('shadowOffset', pos);
},
/**
* set fill which can be a color, linear gradient object,
@ -239,8 +245,8 @@
Kinetic.Global.extend(Kinetic.Shape, Kinetic.Node);
// add getters and setters
Kinetic.Node.addGettersSetters(Kinetic.Shape, ['stroke', 'lineJoin', 'lineCap', 'strokeWidth', 'drawFunc', 'drawHitFunc', 'dashArray']);
Kinetic.Node.addGetters(Kinetic.Shape, ['shadow', 'fill']);
Kinetic.Node.addGettersSetters(Kinetic.Shape, ['stroke', 'lineJoin', 'lineCap', 'strokeWidth', 'drawFunc', 'drawHitFunc', 'dashArray', 'shadowColor', 'shadowBlur', 'shadowOpacity']);
Kinetic.Node.addGetters(Kinetic.Shape, ['shadowOffset', 'fill']);
/**
* set stroke color
@ -298,6 +304,27 @@
* apart
*/
/**
* set shadow color
* @name setShadowColor
* @methodOf Kinetic.Shape.prototype
* @param {String} color
*/
/**
* set shadow blur
* @name setShadowBlur
* @methodOf Kinetic.Shape.prototype
* @param {Number} blur
*/
/**
* set shadow opacity
* @name setShadowOpacity
* @methodOf Kinetic.Shape.prototype
* @param {Number} opacity must be a value between 0 and 1
*/
/**
* get stroke color
* @name getStroke
@ -329,8 +356,26 @@
*/
/**
* get shadow object
* @name getShadow
* get shadow color
* @name getShadowColor
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow blur
* @name getShadowBlur
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow opacity
* @name getShadowOpacity
* @methodOf Kinetic.Shape.prototype
*/
/**
* get shadow offset
* @name getShadowOffset
* @methodOf Kinetic.Shape.prototype
*/

View File

@ -48,7 +48,7 @@
params = [this.attrs.image, 0, 0, width, height];
}
if(this.getShadow()) {
if(this.hasShadow()) {
canvas.applyShadow(this, function() {
that._drawImage(context, params);
});

View File

@ -150,10 +150,8 @@ Test.Modules.NODE = {
height: 50,
fill: 'blue',
offset: [10, 10],
shadow: {
color: 'black',
offset: [20, 20]
}
shadowColor: 'black',
shadowOffset: [20, 20]
});
layer.add(rect);
@ -168,9 +166,7 @@ Test.Modules.NODE = {
rect.setOffset(1, 2);
rect.setShadow({
offset: [3, 4]
});
rect.setShadowOffset([3, 4]);
test(offsetChange, 'offsetChange should have been triggered with setOffset()');
test(!shadowOffsetChange, 'offsetChange should not have been triggered with setShadow()');
@ -212,10 +208,8 @@ Test.Modules.NODE = {
height: 50,
fill: 'blue',
offset: [10, 10],
shadow: {
color: 'black',
offset: [20, 20]
},
shadowColor: 'black',
shadowOffset: [20, 20],
draggable: true,
name: 'myRect'
});
@ -237,20 +231,18 @@ Test.Modules.NODE = {
test(clone.getHeight() === 50, 'clone height should be 50');
test(clone.getFill() === 'red', 'clone fill should be red');
test(rect.getShadow().color === 'black', 'rect shadow color should be black');
test(clone.getShadow().color === 'black', 'clone shadow color should be black');
test(rect.getShadowColor() === 'black', 'rect shadow color should be black');
test(clone.getShadowColor() === 'black', 'clone shadow color should be black');
clone.setShadow({
color: 'green'
});
clone.setShadowColor('green');
/*
* Make sure that when we change a clone object attr that the rect object
* attr isn't updated by reference
*/
test(rect.getShadow().color === 'black', 'rect shadow color should be black');
test(clone.getShadow().color === 'green', 'clone shadow color should be green');
test(rect.getShadowColor() === 'black', 'rect shadow color should be black');
test(clone.getShadowColor() === 'green', 'clone shadow color should be green');
layer.add(rect);
layer.add(clone);
@ -266,7 +258,7 @@ Test.Modules.NODE = {
clone.simulate('click');
test(clicks.toString() === 'myRect,rectClone', 'click order should be myRect followed by rectClone');
},
'clone a group': function(containerId) {
'*clone a group': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
@ -286,10 +278,8 @@ Test.Modules.NODE = {
height: 50,
fill: 'red',
offset: [10, 10],
shadow: {
color: 'black',
offset: [20, 20]
},
shadowColor: 'black',
shadowOffset: [20, 20],
name: 'myRect',
myAttr: 'group rect'
});
@ -300,10 +290,8 @@ Test.Modules.NODE = {
fontSize: 14,
fontFamily: 'Calibri',
textFill: 'blue',
shadow: {
color: 'red',
offset: [20, 20]
},
shadowColor: 'black',
shadowOffset: [20, 20],
name: 'myText'
});
group.add(rect);
@ -397,9 +385,7 @@ Test.Modules.NODE = {
width: 200,
height: 50,
fill: 'blue',
shadow: {
offset: [10, 10]
}
shadowOffset: [10, 10],
});
var circle = new Kinetic.Ellipse({
@ -425,7 +411,7 @@ Test.Modules.NODE = {
test(evt.newVal === 210, 'new width should be 210');
});
rect.on('shadowChange', function() {
rect.on('shadowOffsetChange', function() {
shadowChanged++;
});
@ -436,11 +422,9 @@ Test.Modules.NODE = {
circle.setRadius(70, 20);
rect.setSize(210);
rect.setShadow({
offset: {
x: 20
}
});
rect.setShadowOffset({
x: 20
});
test(widthChanged === 1, 'width change event was not fired correctly');
test(shadowChanged === 1, 'shadow change event not fired correctly');
@ -682,12 +666,10 @@ Test.Modules.NODE = {
frameRate: Math.random() * 6 + 6,
frameRate: 10,
draggable: true,
shadow: {
color: 'black',
blur: 3,
offset: [3, 1],
opacity: 0.3
}
shadowColor: 'black',
shadowBlur: 3,
shadowOffset: [3, 1],
shadowOpacity: 0.3
});
var clone = sprite.clone();
@ -795,7 +777,7 @@ Test.Modules.NODE = {
layer.add(group);
stage.add(layer);
// cache shape
// cache shape
rect.toImage({
x: 8,
y: 8,
@ -813,70 +795,67 @@ Test.Modules.NODE = {
// cache group
group.toImage({
x: 8,
y: 8,
width: 106,
height: 86,
callback: function(imageObj) {
var cachedGroup = new Kinetic.Image({
image: imageObj,
x: 100,
y: 8,
draggable: true
});
group.add(cachedGroup);
layer.draw();
x: 8,
y: 8,
width: 106,
height: 86,
callback: function(imageObj) {
var cachedGroup = new Kinetic.Image({
image: imageObj,
x: 100,
y: 8,
draggable: true
});
group.add(cachedGroup);
layer.draw();
// cache layer
layer.toImage({
x: 8,
y: 8,
width: 200,
height: 86,
callback: function(imageObj) {
// cache layer
layer.toImage({
x: 8,
y: 8,
width: 200,
height: 86,
callback: function(imageObj) {
var cachedLayer = new Kinetic.Image({
image: imageObj,
x: 190,
y: 8,
draggable: true
});
group.add(cachedLayer);
layer.draw();
var cachedLayer = new Kinetic.Image({
image: imageObj,
x: 190,
y: 8,
draggable: true
});
group.add(cachedLayer);
layer.draw();
//var dataUrl = layer.toDataURL();
// cache stage
//var dataUrl = layer.toDataURL();
stage.toImage({
x: 8,
y: 8,
width: 400,
height: 86,
callback: function(imageObj) {
// cache stage
var cachedStage = new Kinetic.Image({
image: imageObj,
x: 8,
y: 100,
draggable: true
});
group.add(cachedStage);
layer.draw();
stage.toImage({
x: 8,
y: 8,
width: 400,
height: 86,
callback: function(imageObj) {
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
var cachedStage = new Kinetic.Image({
image: imageObj,
x: 8,
y: 100,
draggable: true
});
group.add(cachedStage);
layer.draw();
warn(dataUrl === dataUrls['cache shape, group, layer, and stage'], 'problem caching shape, group, layer, and stage');
}
});
var dataUrl = layer.toDataURL();
//console.log(dataUrl);
warn(dataUrl === dataUrls['cache shape, group, layer, and stage'], 'problem caching shape, group, layer, and stage');
}
});
}
});
}
}
});
}
});
}
});
@ -1106,50 +1085,40 @@ Test.Modules.NODE = {
width: 100,
height: 50,
fill: 'red',
shadow: {
color: 'blue',
blur: 12
}
shadowColor: 'blue',
shadowBlur: 12
});
layer.add(rect);
stage.add(layer);
rect.setShadow({
offset: [1, 2]
});
test(rect.getShadow().offset.x === 1, 'shadow offset x should be 1');
test(rect.getShadow().offset.y === 2, 'shadow offset y should be 2');
rect.setShadowOffset([1, 2]);
test(rect.getShadowOffset().x === 1, 'shadow offset x should be 1');
test(rect.getShadowOffset().y === 2, 'shadow offset y should be 2');
// make sure we still have the other properties
test(rect.getShadow().color === 'blue', 'shadow color should still be blue');
test(rect.getShadow().blur === 12, 'shadow blur should still be 12');
test(rect.getShadowColor() === 'blue', 'shadow color should still be blue');
test(rect.getShadowBlur() === 12, 'shadow blur should still be 12');
rect.setShadow({
offset: {
x: 3,
y: 4
}
rect.setShadowOffset({
x: 3,
y: 4
});
test(rect.getShadow().offset.x === 3, 'shadow offset x should be 3');
test(rect.getShadow().offset.y === 4, 'shadow offset y should be 4');
test(rect.getShadowOffset().x === 3, 'shadow offset x should be 3');
test(rect.getShadowOffset().y === 4, 'shadow offset y should be 4');
// test partial setting
rect.setShadow({
offset: {
x: 5
}
rect.setShadowOffset({
x: 5
});
test(rect.getShadow().offset.x === 5, 'shadow offset x should be 5');
test(rect.getShadow().offset.y === 4, 'shadow offset y should be 4');
test(rect.getShadowOffset().x === 5, 'shadow offset x should be 5');
test(rect.getShadowOffset().y === 4, 'shadow offset y should be 4');
// test partial setting
rect.setShadow({
offset: {
rect.setShadowOffset({
y: 6
}
});
test(rect.getShadow().offset.x === 5, 'shadow offset x should be 5');
test(rect.getShadow().offset.y === 6, 'shadow offset y should be 6');
});
test(rect.getShadowOffset().x === 5, 'shadow offset x should be 5');
test(rect.getShadowOffset().y === 6, 'shadow offset y should be 6');
},
'test setOffset': function(containerId) {

View File

@ -167,12 +167,10 @@ Test.Modules.IMAGE = {
y: 40,
image: imageObj,
draggable: true,
shadow: {
color: 'black',
blur: 10,
offset: [20, 20],
opacity: 0.2
}
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: [20, 20],
shadowOpacity: 0.2
});
// override color key with black
@ -410,12 +408,10 @@ Test.Modules.IMAGE = {
y: 40,
image: imageObj,
draggable: true,
shadow: {
color: 'black',
blur: 10,
offset: [20, 20],
opacity: 0.2
}
shadowColor: 'black',
shadowBlur: 10,
shadowOffset: [20, 20],
shadowOpacity: 0.2
});
layer.add(lion);

View File

@ -80,11 +80,9 @@ Test.Modules.LINE = {
lineJoin: 'round',
draggable: true,
dashArray: [30, 10, 0, 10, 10, 20],
shadow: {
color: '#aaa',
blur: 10,
offset: [20, 20]
},
shadowColor: '#aaa',
shadowBlur: 10,
shadowOffset: [20, 20]
//opacity: 0.2
});

View File

@ -88,12 +88,10 @@ Test.Modules.SPRITE = {
frameRate: Math.random() * 6 + 6,
frameRate: 10,
draggable: true,
shadow: {
color: 'black',
blur: 3,
offset: [3, 1],
opacity: 0.3
}
shadowColor: 'black',
shadowBlur: 3,
shadowOffset: [3, 1],
shadowOpacity: 0.3
});
layer.add(sprite);

View File

@ -25,12 +25,11 @@ Test.Modules.Text = {
height: 100,
padding: 10,
shadow: {
color: 'black',
blur: 1,
offset: [10, 10],
opacity: 0.2
},
shadowColor: 'black',
shadowBlur: 1,
shadowOffset: [10, 10],
shadowOpacity: 0.2,
textShadow: {
color: 'red',
blur: 1,
@ -73,12 +72,10 @@ Test.Modules.Text = {
width: 400,
height: 100,
padding: 10,
shadow: {
color: 'black',
blur: 1,
offset: [10, 10],
opacity: 0.2
},
shadowColor: 'black',
shadowBlur: 1,
shadowOffset: [10, 10],
shadowOpacity: 0.2,
cornerRadius: 10,
draggable: true
});
@ -109,7 +106,7 @@ Test.Modules.Text = {
test(text.getWidth() === 400, 'width should be 400');
test(text.getHeight() === 100, 'height should be 100');
test(text.getPadding() === 10, 'padding should be 10');
test(text.getShadow().color === 'black', 'text box shadow color should be black');
test(text.getShadowColor() === 'black', 'text box shadow color should be black');
test(text.getCornerRadius() === 10, 'text box corner radius should be 10');
test(text.getDraggable() === true, 'text should be draggable');
@ -133,9 +130,7 @@ Test.Modules.Text = {
text.setWidth(300);
text.setHeight(75);
text.setPadding(20);
text.setShadow({
color: 'green'
});
text.setShadowColor('green');
text.setCornerRadius(20);
text.setDraggable(false);
@ -154,7 +149,7 @@ Test.Modules.Text = {
test(text.getWidth() === 300, 'width should be 300');
test(text.getHeight() === 75, 'height should be 75');
test(text.getPadding() === 20, 'padding should be 20');
test(text.getShadow().color === 'green', 'text box shadow color should be green');
test(text.getShadowColor() === 'green', 'text box shadow color should be green');
test(text.getCornerRadius() === 20, 'text box corner radius should be 20');
test(text.getDraggable() === false, 'text draggable should be false');
@ -260,12 +255,10 @@ Test.Modules.Text = {
//width: 200,
padding: 20,
align: 'center',
shadow: {
color: 'black',
blur: 1,
offset: [10, 10],
opacity: 0.2
},
shadowColor: 'black',
shadowBlur: 1,
shadowOffset: [10, 10],
shadowOpacity: 0.2,
cornerRadius: 10,
draggable: true,
detectionType: 'path'
@ -308,12 +301,10 @@ Test.Modules.Text = {
//width: 200,
padding: 20,
align: 'center',
textShadow: {
color: 'red',
blur: 1,
offset: [10, 10],
opacity: 0.5
},
shadowColor: 'red',
shadowBlur: 1,
shadowOffset: [10, 10],
shadowOpacity: 0.5,
cornerRadius: 10,
draggable: true,
detectionType: 'path'