diff --git a/Gruntfile.js b/Gruntfile.js index 4846362..b3b8ac7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ '<%= dirs.src %>/Pixi.js', '<%= dirs.src %>/Point.js', '<%= dirs.src %>/Rectangle.js', + '<%= dirs.src %>/Polygon.js', '<%= dirs.src %>/DisplayObject.js', '<%= dirs.src %>/DisplayObjectContainer.js', '<%= dirs.src %>/Sprite.js', diff --git a/Gruntfile.js b/Gruntfile.js index 4846362..b3b8ac7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ '<%= dirs.src %>/Pixi.js', '<%= dirs.src %>/Point.js', '<%= dirs.src %>/Rectangle.js', + '<%= dirs.src %>/Polygon.js', '<%= dirs.src %>/DisplayObject.js', '<%= dirs.src %>/DisplayObjectContainer.js', '<%= dirs.src %>/Sprite.js', diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js index 5080867..9ab1955 100644 --- a/src/pixi/InteractionManager.js +++ b/src/pixi/InteractionManager.js @@ -305,15 +305,56 @@ if(!item.visible)return false; - if(item instanceof PIXI.Sprite) + if(item.hitArea) + { + var worldTransform = item.worldTransform; + var hitArea = item.hitArea; + + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); + + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; + + if (item.hitArea instanceof PIXI.Polygon) { + var inside = false; + + // https://github.com/substack/point-in-polygon/blob/master/index.js + for (var i = 0, j = item.hitArea.points.length - 1; i < item.hitArea.points.length; j = i++) { + var xi = item.hitArea.points[i].x, yi = item.hitArea.points[i].y; + var xj = item.hitArea.points[j].x, yj = item.hitArea.points[j].y; + + var intersect = ((yi > y) != (yj > y)) + && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + if (intersect) inside = !inside; + } + + if (inside) { + return true; + } + } else { + var x1 = hitArea.x; + if(x > x1 && x < x1 + hitArea.width) + { + var y1 = hitArea.y; + + if(y > y1 && y < y1 + hitArea.height) + { + return true; + } + } + } + } + else if(item instanceof PIXI.Sprite) { var worldTransform = item.worldTransform; var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], - a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], - id = 1 / (a00 * a11 + a01 * -a10); + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); - var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; var width = item.texture.frame.width; @@ -324,7 +365,7 @@ if(x > x1 && x < x1 + width) { var y1 = -height * item.anchor.y; - + if(y > y1 && y < y1 + height) { // set the target property if a hit is true! @@ -333,29 +374,6 @@ } } } - else if(item.hitArea) - { - var worldTransform = item.worldTransform; - var hitArea = item.hitArea; - - var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], - a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], - id = 1 / (a00 * a11 + a01 * -a10); - - var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; - var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - - var x1 = hitArea.x; - if(x > x1 && x < x1 + hitArea.width) - { - var y1 = hitArea.y; - - if(y > y1 && y < y1 + hitArea.height) - { - return true; - } - } - } var length = item.children.length; diff --git a/Gruntfile.js b/Gruntfile.js index 4846362..b3b8ac7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,6 +13,7 @@ '<%= dirs.src %>/Pixi.js', '<%= dirs.src %>/Point.js', '<%= dirs.src %>/Rectangle.js', + '<%= dirs.src %>/Polygon.js', '<%= dirs.src %>/DisplayObject.js', '<%= dirs.src %>/DisplayObjectContainer.js', '<%= dirs.src %>/Sprite.js', diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js index 5080867..9ab1955 100644 --- a/src/pixi/InteractionManager.js +++ b/src/pixi/InteractionManager.js @@ -305,15 +305,56 @@ if(!item.visible)return false; - if(item instanceof PIXI.Sprite) + if(item.hitArea) + { + var worldTransform = item.worldTransform; + var hitArea = item.hitArea; + + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); + + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; + + if (item.hitArea instanceof PIXI.Polygon) { + var inside = false; + + // https://github.com/substack/point-in-polygon/blob/master/index.js + for (var i = 0, j = item.hitArea.points.length - 1; i < item.hitArea.points.length; j = i++) { + var xi = item.hitArea.points[i].x, yi = item.hitArea.points[i].y; + var xj = item.hitArea.points[j].x, yj = item.hitArea.points[j].y; + + var intersect = ((yi > y) != (yj > y)) + && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + if (intersect) inside = !inside; + } + + if (inside) { + return true; + } + } else { + var x1 = hitArea.x; + if(x > x1 && x < x1 + hitArea.width) + { + var y1 = hitArea.y; + + if(y > y1 && y < y1 + hitArea.height) + { + return true; + } + } + } + } + else if(item instanceof PIXI.Sprite) { var worldTransform = item.worldTransform; var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], - a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], - id = 1 / (a00 * a11 + a01 * -a10); + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10); - var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; + var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; var width = item.texture.frame.width; @@ -324,7 +365,7 @@ if(x > x1 && x < x1 + width) { var y1 = -height * item.anchor.y; - + if(y > y1 && y < y1 + height) { // set the target property if a hit is true! @@ -333,29 +374,6 @@ } } } - else if(item.hitArea) - { - var worldTransform = item.worldTransform; - var hitArea = item.hitArea; - - var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], - a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], - id = 1 / (a00 * a11 + a01 * -a10); - - var x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id; - var y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - - var x1 = hitArea.x; - if(x > x1 && x < x1 + hitArea.width) - { - var y1 = hitArea.y; - - if(y > y1 && y < y1 + hitArea.height) - { - return true; - } - } - } var length = item.children.length; diff --git a/src/pixi/Polygon.js b/src/pixi/Polygon.js new file mode 100644 index 0000000..aca9aa7 --- /dev/null +++ b/src/pixi/Polygon.js @@ -0,0 +1,31 @@ +/** + * @author Adrien Brault + */ + +/** + * @class Polygon + * @constructor + * @param points {Array} + */ +PIXI.Polygon = function(points) +{ + this.points = points; +} + +/** + * @method clone + * @return a copy of the polygon + */ +PIXI.Polygon.clone = function() +{ + var points = []; + for (var i=0; i