rewrote cropping logic from last pull request, fixed serialization issue in unit test, added new unit tests, and added getX() and getY() methods

This commit is contained in:
Eric Rowell 2012-04-27 19:08:45 -07:00
parent f5735b3462
commit 508bfb7a9b
6 changed files with 190 additions and 39 deletions

101
dist/kinetic-core.js vendored
View File

@ -3,7 +3,7 @@
* http://www.kineticjs.com/
* Copyright 2012, Eric Rowell
* Licensed under the MIT or GPL Version 2 licenses.
* Date: Apr 15 2012
* Date: Apr 27 2012
*
* Copyright (C) 2011 - 2012 by Eric Rowell
*
@ -310,6 +310,20 @@ Kinetic.Node.prototype = {
this.attrs[key].y = val.y;
}
break;
case 'crop':
if(val.x !== undefined) {
this.attrs[key].x = val.x;
}
if(val.y !== undefined) {
this.attrs[key].y = val.y;
}
if(val.width !== undefined) {
this.attrs[key].width = val.width;
}
if(val.height !== undefined) {
this.attrs[key].height = val.height;
}
break;
/*
* config properties that we don't want in attrs
*/
@ -441,6 +455,18 @@ Kinetic.Node.prototype = {
setY: function(y) {
this.attrs.y = y;
},
/**
* get node x position
*/
getX: function() {
return this.attrs.x;
},
/**
* get node y position
*/
getY: function() {
return this.attrs.y;
},
/**
* set detection type
* @param {String} type can be "path" or "pixel"
@ -2369,6 +2395,7 @@ Kinetic.Rect = function(config) {
}
this.attrs.width = 0;
this.attrs.height = 0;
this.attrs.cornerRadius = 0;
this.shapeType = "Rect";
@ -2376,7 +2403,22 @@ Kinetic.Rect = function(config) {
var context = this.getContext();
context.beginPath();
this.applyLineJoin();
context.rect(0, 0, this.attrs.width, this.attrs.height);
if(this.attrs.cornerRadius === 0) {
// simple rect - don't bother doing all that complicated maths stuff.
context.rect(0, 0, this.attrs.width, this.attrs.height);
}
else {
// arcTo would be nicer, but browser support is patchy (Opera)
context.moveTo(this.attrs.cornerRadius, 0);
context.lineTo(this.attrs.width - this.attrs.cornerRadius, 0);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI * 3 / 2, 0, false);
context.lineTo(this.attrs.width, this.attrs.height - this.attrs.cornerRadius);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, 0, Math.PI / 2, false);
context.lineTo(this.attrs.cornerRadius, this.attrs.height);
context.arc(this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI / 2, Math.PI, false);
context.lineTo(0, this.attrs.cornerRadius);
context.arc(this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI, Math.PI * 3 / 2, false);
}
context.closePath();
this.fillStroke();
};
@ -2430,7 +2472,20 @@ Kinetic.Rect.prototype = {
width: this.attrs.width,
height: this.attrs.height
};
}
},
/**
* set corner radius
* @param {Number} radius
*/
setCornerRadius: function(radius) {
this.attrs.cornerRadius = radius;
},
/**
* get corner radius
*/
getCornerRadius: function() {
return this.attrs.cornerRadius;
},
};
// extend Shape
@ -2501,6 +2556,12 @@ Kinetic.Image = function(config) {
if(this.attrs === undefined) {
this.attrs = {};
}
this.attrs.crop = {
x: 0,
y: 0,
width: undefined,
height: undefined
};
// special
this.image = config.image;
@ -2510,14 +2571,27 @@ Kinetic.Image = function(config) {
if(this.image !== undefined) {
var width = this.attrs.width !== undefined ? this.attrs.width : this.image.width;
var height = this.attrs.height !== undefined ? this.attrs.height : this.image.height;
var cropX = this.attrs.crop.x;
var cropY = this.attrs.crop.y;
var cropWidth = this.attrs.crop.width;
var cropHeight = this.attrs.crop.height;
var canvas = this.getCanvas();
var context = this.getContext();
context.beginPath();
this.applyLineJoin();
context.rect(0, 0, width, height);
context.closePath();
this.fillStroke();
context.drawImage(this.image, 0, 0, width, height);
// if cropping
if(cropWidth !== undefined && cropHeight !== undefined) {
context.drawImage(this.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height);
}
// no cropping
else {
context.drawImage(this.image, 0, 0, width, height);
}
}
};
// call super constructor
@ -2583,6 +2657,25 @@ Kinetic.Image.prototype = {
width: this.attrs.width,
height: this.attrs.height
};
},
/**
* return cropping
*/
getCrop: function() {
return this.attrs.crop;
},
/**
* set cropping
* @param {Object} crop
* @config {Number} [x] crop x
* @config {Number} [y] crop y
* @config {Number} [width] crop width
* @config {Number} [height] crop height
*/
setCrop: function(config) {
var c = {};
c.crop = config;
this.setAttrs(c);
}
};
// extend Shape

File diff suppressed because one or more lines are too long

View File

@ -158,6 +158,20 @@ Kinetic.Node.prototype = {
this.attrs[key].y = val.y;
}
break;
case 'crop':
if(val.x !== undefined) {
this.attrs[key].x = val.x;
}
if(val.y !== undefined) {
this.attrs[key].y = val.y;
}
if(val.width !== undefined) {
this.attrs[key].width = val.width;
}
if(val.height !== undefined) {
this.attrs[key].height = val.height;
}
break;
/*
* config properties that we don't want in attrs
*/
@ -289,6 +303,18 @@ Kinetic.Node.prototype = {
setY: function(y) {
this.attrs.y = y;
},
/**
* get node x position
*/
getX: function() {
return this.attrs.x;
},
/**
* get node y position
*/
getY: function() {
return this.attrs.y;
},
/**
* set detection type
* @param {String} type can be "path" or "pixel"

View File

@ -12,8 +12,12 @@ Kinetic.Image = function(config) {
if(this.attrs === undefined) {
this.attrs = {};
}
this.attrs.cropX = 0;
this.attrs.cropY = 0;
this.attrs.crop = {
x: 0,
y: 0,
width: undefined,
height: undefined
};
// special
this.image = config.image;
@ -23,16 +27,27 @@ Kinetic.Image = function(config) {
if(this.image !== undefined) {
var width = this.attrs.width !== undefined ? this.attrs.width : this.image.width;
var height = this.attrs.height !== undefined ? this.attrs.height : this.image.height;
var cropWidth = this.attrs.cropWidth !== undefined ? this.attrs.cropWidth : this.image.width;
var cropHeight = this.attrs.cropHeight !== undefined ? this.attrs.cropHeight : this.image.height;
var cropX = this.attrs.crop.x;
var cropY = this.attrs.crop.y;
var cropWidth = this.attrs.crop.width;
var cropHeight = this.attrs.crop.height;
var canvas = this.getCanvas();
var context = this.getContext();
context.beginPath();
this.applyLineJoin();
context.rect(0, 0, width, height);
context.closePath();
this.fillStroke();
context.drawImage(this.image,this.attrs.cropX, this.attrs.cropY, cropWidth, cropHeight, 0, 0, width, height);
// if cropping
if(cropWidth !== undefined && cropHeight !== undefined) {
context.drawImage(this.image, cropX, cropY, cropWidth, cropHeight, 0, 0, width, height);
}
// no cropping
else {
context.drawImage(this.image, 0, 0, width, height);
}
}
};
// call super constructor
@ -102,26 +117,21 @@ Kinetic.Image.prototype = {
/**
* return cropping
*/
getCropping: function() {
return {
cropX: this.attrs.cropX,
cropY: this.attrs.cropY,
cropWidth: this.attrs.cropWidth,
cropHeight: this.attrs.cropHeight
};
getCrop: function() {
return this.attrs.crop;
},
/**
* set cropping
* @param {Number} cropX
* @param {Number} cropY
* @param {Number} cropWidth
* @param {Number} cropHeight
* @param {Object} crop
* @config {Number} [x] crop x
* @config {Number} [y] crop y
* @config {Number} [width] crop width
* @config {Number} [height] crop height
*/
setCropping: function() {
this.attrs.cropX = cropX;
this.attrs.cropY = cropY;
this.attrs.cropWidth = cropWidth;
this.attrs.cropHeight = cropHeight;
setCrop: function(config) {
var c = {};
c.crop = config;
this.setAttrs(c);
}
};
// extend Shape

View File

@ -22,7 +22,7 @@ Kinetic.Rect = function(config) {
var context = this.getContext();
context.beginPath();
this.applyLineJoin();
if (this.attrs.cornerRadius === 0) {
if(this.attrs.cornerRadius === 0) {
// simple rect - don't bother doing all that complicated maths stuff.
context.rect(0, 0, this.attrs.width, this.attrs.height);
}
@ -30,13 +30,13 @@ Kinetic.Rect = function(config) {
// arcTo would be nicer, but browser support is patchy (Opera)
context.moveTo(this.attrs.cornerRadius, 0);
context.lineTo(this.attrs.width - this.attrs.cornerRadius, 0);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI*3/2, 0, false);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI * 3 / 2, 0, false);
context.lineTo(this.attrs.width, this.attrs.height - this.attrs.cornerRadius);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, 0, Math.PI/2, false);
context.arc(this.attrs.width - this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, 0, Math.PI / 2, false);
context.lineTo(this.attrs.cornerRadius, this.attrs.height);
context.arc(this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI/2, Math.PI, false);
context.arc(this.attrs.cornerRadius, this.attrs.height - this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI / 2, Math.PI, false);
context.lineTo(0, this.attrs.cornerRadius);
context.arc(this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI, Math.PI*3/2, false);
context.arc(this.attrs.cornerRadius, this.attrs.cornerRadius, this.attrs.cornerRadius, Math.PI, Math.PI * 3 / 2, false);
}
context.closePath();
this.fillStroke();

View File

@ -674,7 +674,7 @@ Test.prototype.tests = {
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 200,
y: 100,
y: 90,
width: 100,
height: 50,
fill: 'green',
@ -686,7 +686,9 @@ Test.prototype.tests = {
scale: {
x: 2,
y: 2
}
},
cornerRadius: 15,
draggable: true
});
layer.add(rect);
@ -765,14 +767,35 @@ Test.prototype.tests = {
y: 60,
image: imageObj,
width: 100,
height: 100,
centerOffset: {
x: 50,
y: imageObj.height / 2
y: 30
},
crop: {
x: 20,
y: 20,
width: 200,
height: 250
}
});
layer.add(darth);
stage.add(layer);
test(darth.getX() === 200, 'x should be 200');
test(darth.getY() === 60, 'y should be 60');
test(darth.getWidth() === 100, 'width should be 100');
test(darth.getHeight() === 100, 'height should be 100');
test(darth.getCenterOffset().x === 50, 'center offset x should be 50');
test(darth.getCenterOffset().y === 30, 'center offset y should be 30');
var crop = darth.getCrop();
test(crop.x === 20, 'crop x should be 20');
test(crop.y === 20, 'crop y should be 20');
test(crop.width === 200, 'crop width should be 200');
test(crop.height === 250, 'crop height should be 250');
};
imageObj.src = '../darth-vader.jpg';
},
@ -800,8 +823,7 @@ Test.prototype.tests = {
stage.add(layer);
var json = stage.toJSON();
test(json === '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":50,"y":150},"dragConstraint":"none","dragBounds":{},"draggable":false,"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}', 'problem serializing stage');
test(json === '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"crop":{"x":0,"y":0},"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":50,"y":150},"dragConstraint":"none","dragBounds":{},"draggable":false,"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}', 'problem serializing stage');
};
imageObj.src = '../darth-vader.jpg';
},
@ -814,7 +836,7 @@ Test.prototype.tests = {
height: 200
});
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":50,"y":150},"dragConstraint":"none","dragBounds":{},"draggable":false,"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}';
var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"crop":{"x":0,"y":0},"detectionType":"path","visible":true,"listening":true,"alpha":1,"x":200,"y":60,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":50,"y":150},"dragConstraint":"none","dragBounds":{},"draggable":false,"id":"darth"},"nodeType":"Shape","shapeType":"Image"}]}]}';
stage.load(json);