Collision detection using kineticJS (getIntersection function not working) - javascript

I am trying to recreate the game http://www.sinuousgame.com/ and started studying html5 canvas and kineticJS.
Recently i came across the getIntersection function and coudnt find much details regarding it.But with what i had ,i did make a code to get the Collision detection done using getIntersection() function.
But it doesnt seem to be working.
As you can see, My Fiddle: http://jsfiddle.net/p9fnq/8/
//The working player code
var LimitedArray = function(upperLimit) {
var storage = [];
// default limit on length if none/invalid supplied;
upperLimit = +upperLimit > 0 ? upperLimit : 100;
this.push = function(item) {
storage.push(item);
if (storage.length > upperLimit) {
storage.shift();
}
return storage.length;
};
this.get = function(flag) {
return storage[flag];
};
this.iterateItems = function(iterator) {
var flag, l = storage.length;
if (typeof iterator !== 'function') {
return;
}
for (flag = 0; flag < l; flag++) {
iterator(storage[flag]);
}
};
};
var tail = new LimitedArray(50);
var flag = 0, jincr = 0;
var stage = new Kinetic.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
listening: true
});
var layer = new Kinetic.Layer({
listening: true
});
stage.add(layer);
var player = new Kinetic.Circle({
x: 20,
y: 20,
radius: 6,
fill: 'cyan',
stroke: 'black',
draggable: true
});
var line = new Kinetic.Line({
points: [],
stroke: 'cyan',
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
layer.add(player);
// move the circle with the mouse
stage.getContent().addEventListener('mousemove', function() {
player.position(stage.getPointerPosition());
var obj = {
x: stage.getPointerPosition().x,
y: stage.getPointerPosition().y
};
tail.push(obj);
var arr = [];
tail.iterateItems(function(p) {
arr.push(p.x, p.y);
});
line.points(arr);
});
var x = 0;
var y = 0;
var noOfEnemies = 200;
var enemyArmada = new Array();
createEnemy();
function createEnemy() {
for (var i = 0; i < noOfEnemies; i++) {
var enemy = new Kinetic.Circle({
x: Math.random() * window.innerWidth,
y: Math.random() * window.innerHeight,
radius: 4.5 + 1.5 * Math.random(),
fill: 'red',
stroke: 'black'
});
enemy.speedX = enemy.speedY = (0.5 + Math.random() * 50);
enemyArmada.push(enemy);
layer.add(enemy);
}
}
var checkCollide = function() {
var position = stage.getPointerPosition();
if(position == null)
position = player.position();
if(position == null)
position = {x:0,y:0};
var collided = stage.getIntersection(position);
console.log(position);
if (typeof collided !== 'Kinetic.Shape') {
console.log("not shape");
}
else {
console.log("BOOOM!!!");
}
};
var anim = new Kinetic.Animation(function(frame) {
checkCollide();
for (var i = 0; i < noOfEnemies; i++) {
var e = enemyArmada[i];
e.position({
x: e.position().x - e.speedX * (frame.timeDiff / 400),
y: e.position().y + e.speedY * (frame.timeDiff / 400)
});
if (e.position().y < 0 || e.position().x < 0) {
e.position({
x: (Math.random() * (window.innerWidth + 600)),
y: -(Math.random() * window.innerHeight)
});
}
}
}, layer);
anim.start();
I need the collision to be detected. The function i have written here is checkCollide and its called within the kinetic.Animation function.
Can anyone help me out with this??
(If you don't know the solution,please do like the post,i need the solution badly)

The source of the problem
getIntersection(point) means "is any object at this point".
Since the point you're using is the player's position, getIntersection will always return true because player is always at its own position !
One solution
Put your player on one layer and all enemies on a separate layer.
That way you can hit test the enemy layer without the interference of the player object.
Code and a Demo: http://jsfiddle.net/m1erickson/JCfW8/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var enemyLayer = new Kinetic.Layer();
stage.add(enemyLayer);
var playerLayer = new Kinetic.Layer();
stage.add(playerLayer);
var player = new Kinetic.Circle({
x:100,
y:100,
radius: 10,
fill: 'green',
draggable: true
});
player.on("dragmove",function(){
if(enemyLayer.getIntersection(player.position())){
this.fill("red");
playerLayer.draw();
}
});
playerLayer.add(player);
playerLayer.draw();
var enemy = new Kinetic.Circle({
x:200,
y:100,
radius: 20,
fill: 'blue',
draggable: true
});
enemyLayer.add(enemy);
enemyLayer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag the green player<br>Player will turn red if it collides<br>with the blue enemy</h4>
<div id="container"></div>
</body>
</html>
Another solution
Mathematically test the player against every enemy:
Warning: untested code--some tweaking might be required
function playerEnemyCollide(){
var playerX=player.x();
var playerY=player.y();
var playerRadius=player.radius();
for(var i=0;i<enemyArmada.length;i++){
var e=enemyArmada[i];
if(circlesColliding(playerX,playerY,playerRadius,e.x,e.y,e.radius)){
return(true);
}
}
return(false);
}
function circlesColliding(cx1,cy1,radius1,cx2,cy2,radius2){
var dx=cx2-cx1;
var dy=cy2-cy1;
return(dx*dx+dy*dy<(radius1*2+radius2*2);
}

Related

How can i keep the Konvas layer centered after resize?

So i'm using Konvajs, to draw segments, only vertical and horizontal. My problem is the following, when i start the debug, if the window is small and then i click to maximize, the layer will stay with same size as when small. Ex:
here it s the Javascript file for the Konva creation:
function setUpDesignMap(){
var width = $('#designContainer').width();
var height = $('#designContainer').height();
var blockSnapSize = gridSize;
var isDrawing = false;
var drawShape = null;
designStage = new Konva.Stage({
container: 'designContainer',
width: width,
height: height,
draggable: true,
name:'designStage'
// dragBoundFunc: function(pos) {
// var newY = pos.y < 0 ? 0 : pos.y;
// var newX = pos.x < 0 ? 0 : pos.x;
// return {
// x: newX,
// y: newY
// };
// }
});
/*Set up grid*/
var gridLayer = new Konva.Layer();
var tipLayer = new Konva.Layer();
drawLayer = new Konva.Layer();
segGrp = new Konva.Group({name:'segments'});
/* draw grid */
for (var i = 0; i < 240; i++) {
gridLayer.add(new Konva.Line({
points: [Math.round(i * blockSnapSize), 0, Math.round(i * blockSnapSize), 120*blockSnapSize],
stroke: '#888',
strokeWidth: 0.5,
}));
}
gridLayer.add(new Konva.Line({points: [0,0,10,10]}));
for (var j = 0; j < 120; j++) {
gridLayer.add(new Konva.Line({
points: [0, Math.round(j * blockSnapSize), 240*blockSnapSize, Math.round(j * blockSnapSize)],
stroke: '#888',
strokeWidth: 0.5,
}));
}
/* Stage initial position*/
zoomVars_design = {scale: 1, factor: 1.1, origin: {x:-100*gridSize,y:-50*gridSize}};
designStage.position(zoomVars_design.origin);
designStage.scale({ x: 1, y: 1 });
/*Set up mouse tip*/
var mouseTip = new Konva.Rect({
width: 6,
height: 6,
opacity:0,
fill: '#FFCC00',
stroke: '#FFCC00'
});
tipLayer.add(mouseTip);
/* Set up length indicator */
var lenShape = new Konva.Line({
points:[],
opacity: 1,
strokeWidth: 1,
stroke: '#000',
dash:[7,5]
});
gridLayer.add(lenShape);
/* Set up length text*/
var lenText = new Konva.Text({
align: 'center',
verticalAlign: 'middle',
fontSize: 12
});
gridLayer.add(lenText);
var lenSide = new Konva.Line({
points:[],
opacity: 1,
strokeWidth: 1,
stroke: '#000',
dash:[7,5]
});
gridLayer.add(lenSide);
/*Mouse handlers*/
//remove default behaviour for the container
$("#designContainer").on('mousedown', function(e){
e.preventDefault();
});
$("#designContainer").on('contextmenu', function(e){
e.preventDefault();
});
//mouse handlers on stage
designStage.on('contentMousedown', function (e) {
if(e.evt.button == 0){
designStage.draggable(false);
}
else{
designStage.draggable(true);
return;
}
if(mouseMode == 0){ //draw mode
var startPoint = {x:(mouseTip.attrs.x+3), y:(mouseTip.attrs.y+3)};
if(!isDrawing){
if(!isIntersection(startPoint)){ //cannot be intersection to avoid crosses
//check if there's an intersection on the begining
if(isCorner(startPoint)){
intersectingSeg = false;
intersectingCorner = true;
console.log('intersectingSeg = false')
}
else{
//check if its on an existing segment
var isonseg = isOnSegment(startPoint);
if(isonseg.b){
//validate resulting segments length
var intercected = getSegmentsArray(isonseg.d)[isonseg.i];
var res = breakSegAtIntersection(startPoint,intercected);
if(isValidLength(res[0].start,res[0].end) && isValidLength(res[1].start,res[1].end)){
intersectingSeg = true;
intersectingCorner = false;
console.log('>>>>>>>Intersecting Segment at start')
}
else{
consoleAdd('Resulting segments are too small to you');
return;
}
}
}
//start drawing
drawShape = new Konva.Line({
points: [startPoint.x, startPoint.y],
strokeWidth: 15,
stroke: 'black',
opacity: 0.5,
dir:'h'
});
drawShape.on('mouseover', function (e) {
if(mouseMode == 1){
this.stroke('#031C4D');
drawLayer.draw();
}
});
drawShape.on('mouseout', function (e) {
if(mouseMode == 1){
this.stroke('black');
drawLayer.draw();
}
});
drawShape.on('mouseup', function (e) {
if(mouseMode == 1){
this.stroke('#092C70');
drawLayer.draw();
}
});
segGrp.add(drawShape);
drawLayer.add(segGrp);
drawLayer.draw();
isDrawing = true;
}
else{
consoleAdd('Cannot start on an intersection');
}
gridLayer.draw();
}
}
});
So i want the layer not to be that small, always refitting. Thank you all for your attention!
You need to manually resize your stage when the size of container element is changed.
window.addEventListener('resize', () => {
var width = $('#designContainer').width();
var height = $('#designContainer').height();
designStage.width(width);
designStage.height(height);
})
You may also need to apply the scale to the stage.
Take a look into related demo: https://konvajs.org/docs/sandbox/Responsive_Canvas.html

Why I cannot draw multiple curved arrows with sceneFunc() in Shape object using KonvaJS?

I am inspired with KonvaJS tutorial Modify Curves with Anchor Points to make my own example which is to create multiple custom arrows.
on click on the selectionBox create an anchor.
on the creation of the third anchor create the curved arrow.
on the fourth click reset all variables in order to draw a new curved arrow.
var width = window.innerWidth;
var height = window.innerHeight;
// globals
var selectionBoxLayer, curveLayer, lineLayer, anchorLayer, quad, bezier;
function updateDottedLines() {
var q = quad;
var quadLine = lineLayer.get('#quadLine')[0];
quadLine.setPoints([q.start.attrs.x, q.start.attrs.y, q.control.attrs.x, q.control.attrs.y, q.end.attrs.x, q.end.attrs.y]);
lineLayer.draw();
}
function buildAnchor(x, y) {
var anchor = new Konva.Circle({
x: x,
y: y,
radius: 20,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
draggable: true
});
// add hover styling
anchor.on('mouseover', function() {
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
anchorLayer.draw();
});
anchor.on('mouseout', function() {
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
anchorLayer.draw();
});
anchor.on('dragend', function() {
drawCurves();
updateDottedLines();
});
anchorLayer.add(anchor);
anchorLayer.draw();
return anchor;
}
function drawCurves() {
var context = curveLayer.getContext();
var arrowLine = new Konva.Shape({
sceneFunc: function(context){
debugger;
// draw quad
context.beginPath();
context.moveTo(quad.start.attrs.x, quad.start.attrs.y);
context.quadraticCurveTo(quad.control.attrs.x, quad.control.attrs.y, quad.end.attrs.x, quad.end.attrs.y);
//Draw Arrow Head
var headlen = 10; // length of head in pixels
var angle = Math.atan2(quad.end.attrs.y - quad.control.attrs.y, quad.end.attrs.x - quad.control.attrs.x);
context.lineTo(quad.end.attrs.x-headlen*Math.cos(angle-Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle-Math.PI/6));
context.moveTo(quad.end.attrs.x, quad.end.attrs.y);
context.lineTo(quad.end.attrs.x- headlen*Math.cos(angle+Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle+Math.PI/6));
context.fillStrokeShape(this);
},
stroke: 'black',
strokeWidth: 4
});
curveLayer.add(arrowLine);
curveLayer.draw();
}
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
selectionBoxLayer = new Konva.Layer();
anchorLayer = new Konva.Layer();
lineLayer = new Konva.Layer();
// curveLayer just contains a canvas which is drawn
// onto with the existing canvas API
curveLayer = new Konva.Layer();
var quadLine = new Konva.Line({
dash: [10, 10, 0, 10],
strokeWidth: 3,
stroke: 'black',
lineCap: 'round',
id: 'quadLine',
opacity: 0.3,
points: [0, 0]
});
// add dotted line connectors
lineLayer.add(quadLine);
quad = {};
// keep curves insync with the lines
anchorLayer.on('beforeDraw', function() {
if(quad.start && quad.control && quad.end){
drawCurves();
updateDottedLines();
}
});
var selectionBoxBackground = new Konva.Rect({
x: 0,
y: 0,
height:stage.height(),
width: stage.width(),
fill: 'transparent',
draggable: false,
name: 'selectionBoxBackground'
});
selectionBoxLayer.add(selectionBoxBackground);
var clickCounter = 0;
selectionBoxBackground.on("click", function(){
clickCounter +=1;
var mousePos = {};
switch(clickCounter){
case 1:
mousePos = stage.getPointerPosition();
quad.start = buildAnchor(mousePos.x, mousePos.y);
break;
case 2:
mousePos = stage.getPointerPosition();
quad.control = buildAnchor(mousePos.x, mousePos.y);
break;
case 3:
mousePos = stage.getPointerPosition();
quad.end = buildAnchor(mousePos.x, mousePos.y);
drawCurves();
updateDottedLines();
break;
default:
clickCounter = 0;
quad = {};
anchorLayer.destroyChildren();
anchorLayer.draw();
}
});
stage.add(curveLayer);
stage.add(lineLayer);
stage.add(selectionBoxLayer);
stage.add(anchorLayer);
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<script src="https://cdn.rawgit.com/konvajs/konva/0.11.1/konva.min.js"></script>
<body>
<div id="container"></div>
</body>
P.S Please note when I write in the browser console curveLayer.children, it will bring all created curved arrows.
Hint: I think on the creation of new Shape() the values of all created shapes will be changed to the new one.
I don't know what I am missing.

kinetic js textPath: draggable didn't work

var stages = new Array() ;
var limites = new Array() ;
numStage=0;
r = {
'x':65,
'y':120,
'xwidth':335,
'yheight':210
};
limites.push(r);
stages[numStage] = new Kinetic.Stage({
container: 'cmg_canvas_'+numStage,
width: 450,
height: 450
});
//creation image
obj = new Image();
obj.src = 'http://i.imgur.com/zFZgKuS.jpg';
image = new Kinetic.Image({
image: obj,
width: 450,
height: 450
});
// add image to calque
layer = new Kinetic.Layer();
layer.add(image);
stages[numStage].add(layer); //add image to canvas
layer = new Kinetic.Layer();
//set limit x y h l
/*var rect = new Kinetic.Rect({
name: 'limite',
x: limites[numStage].x,
y: limites[numStage].y,
width: limites[numStage].xwidth,
height: limites[numStage].yheight,
stroke: 'black',
strokeWidth: 0.5
});*/
//layer.add(rect);// add to canvas
stages[numStage].add(layer);
$('.cmg_text').live('blur', function(){
idText = 'cmg_line0';
numStage = 0;
drawTextPath(numStage, idText,$(this).val(),50,22,numStage);
//text = getText(this).text;
});
function getSVG(x,y,w,verif) {
halfw = parseFloat((w/2).toFixed(2));
x1 = parseFloat((halfw/2).toFixed(2));
x2 = parseFloat(halfw + x1);
if(parseInt(verif))
{
y1 = parseFloat(y) * 2 +18;
y2 = parseFloat(y) * 2 +18;
}
else
{
y1 = -18;
y2 = -18;
}
str = 'M '+x+','+y+' C '+x1+','+y1+' '+x2+','+y2+' '+w+','+y;
return str;
}
function drawTextPath(numStage, textId,text,valueSlider, newFontSize,numStage){
//'M 0,115 C42,-18 126,-18 165,115';
//'M 0,115 C45,230 180,230 180,115';
var arcOnly = 0;
if(textId == 'cmg_line0')
{
console.log('limites[numStage].yheight/2'+limites[numStage].yheight/2);
console.log('limites[numStage].xwidth'+limites[numStage].xwidth);
svg = getSVG(0,valueSlider,valueSlider*6.3,0);
arcOnly = 0;
}
//alert(svg);
console.log(parseFloat(limites[numStage].y));
console.log(parseFloat(arcOnly));
console.log(parseFloat(limites[numStage].y - arcOnly));
var layer = new Kinetic.Layer({name:'textPathLayer',draggable:true});
var textpath = new Kinetic.TextPath({
name:'TextPath',
id: textId,
//x: 0,
//x: limites[numStage].x + limites[numStage].xwidth/2,
//y: 0,
//y: limites[numStage].y + limites[numStage].yheight/2,
x: limites[numStage].x ,
y: limites[numStage].y + limites[numStage].yheight/2,
fill: '#000',
fontSize: newFontSize,
fontFamily: 'Arial',
text: text,
//offsetX:0,
//offsetY:0,
draggable: true,
dragBoundFunc: function(pos){
p = textParams(this, pos);
return {x: p.newX, y: p.newY};
},
data: svg
});
//
layer.add(textpath);
stages[numStage].add(layer);
//layer.moveToTop();
//layer.draw();
//stages[0].draw();
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/kineticjs/4.6.0/kinetic.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div id="cmg_canvas_0"></div>
<input type='text' class='cmg_text' />
I have to draw a draggable textpath with kineticjs, with text given by an input text, the action is triggered in blur.
I have a stage that contain 3 layers;
Layer for the background, and one layer for the textpath.
My problem that the draggable in the textpath is not working,
i tried to set the text layer in the top, but i didn't get it draggable.
This is my jsfiddle
I have a doubt of inner layer problem.
Thanks in advance.

Adding objects into an array in javascript

I am trying to get the mouse pointer coordinates and store them into an array(tail) such that the array is limited only to 100 objects. If extra objects comes,the old one's are to be replaced with the new one's. Basically like a queue.
Basically i am trying to create a trail after the basic circle using a circle of smaller radius.
Here's my js:
$(document).ready(function() {
var tail = {
x:0,
y:0
};
var i = 0;
var stage = new Kinetic.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
listening: true
});
var layer = new Kinetic.Layer({
listening: true
});
var layer = new Kinetic.Layer();
var player = new Kinetic.Circle({
x: 20,
y: 20,
radius: 6,
fill: 'cyan',
stroke: 'black',
draggable: true
});
var pixel = new Kinetic.Circle({
x: 20,
y: 20,
radius: 2,
width: stage.getWidth(),
height: stage.getHeight(),
fill: "white"
});
layer.add(player);
stage.add(layer);
// move the circle with the mouse
stage.getContent().addEventListener('mousemove', function() {
player.setPosition(stage.getPointerPosition());
console.log(stage.getPointerPosition());
var obj = {
x: stage.getPointerPosition().x,
y: stage.getPointerPosition().y
}
tail[i].push(obj);
++i;
console.log(tail[i]);
// pixel.setPosition(tail[i], tail[i + 1]);
layer.draw();
});
});
And here's the html:
<!DOCTYPE html>
<html>
<head>
<title>Collision Detection</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="../css/style.css"/>
</head>
<body>
<div id="container" style=" background:#000; margin:auto; float:left;"></div>
<script src="../js/jquery.min.js"></script>
<script src="../js/kinetic-v5.0.0.min.js"></script>
<script src="../js/main_kinetic.js"></script>
</body>
</html>
Output:
Uncaught TypeError: Cannot call method 'push' of undefined main_kinetic.js:46
Object {x: 656, y: 175} --> console output which returns the cursor position.
Here's the fiddle: http://jsfiddle.net/BVeTH/
You could create your own container for your data points that handles only keeping 100 (or however many you want). Something like this:
var LimitedArray = function (upperLimit) {
var storage = [];
// default limit on length if none/invalid supplied;
upperLimit = +upperLimit > 0 ? upperLimit : 100;
this.push = function (item) {
storage.push(item);
if (storage.length > upperLimit) {
storage.shift();
}
return storage.length;
};
this.get = function (i) {
return storage[i];
};
this.iterateItems = function (iterator) {
var i, l = storage.length;
if (typeof iterator !== 'function') { return; }
for (i = 0; i < l; i++) {
iterator(storage[i]);
}
};
};
(see here: http://jsfiddle.net/Frm27/4/)
Then you can track your datapoints easily:
var trail = new LimitedArray(100);
// code...
// move the circle with the mouse
stage.getContent().addEventListener('mousemove', function() {
player.setPosition(stage.getPointerPosition());
console.log(stage.getPointerPosition());
var obj = {
x: stage.getPointerPosition().x,
y: stage.getPointerPosition().y
}
trail.push(obj);
trail.iterateItems(function (item) {
// Do something with each item.x and item.y
});
// pixel.setPosition(tail[i], tail[i + 1]);
layer.draw();
});
Unless you reassign it somewhere I am not seeing tail is not an array.
var tail = {
x:null,
y:0
};
If you wanted to store objects with x and y coordinates in it you would need
var tail = [{
x:null,
y:0
}];
tail.push(...);

Anchor points should only visible when mouse goes over them

The code below creates a scalable and draggable triangle with anchor points at its vertices. i want that the anchor points should only visible when mouse goes over them??
and also, how collision detection can be implemented to avoid drawing of other spaces inside the triangle?
<html>
<head>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v3.10.0.js"></script>
<script type="text/javascript">
// the circle anchor points
function buildAnchor(layer, x, y, name) {
var anchor = new Kinetic.Circle({
x: x,
y: y,
radius: 6,
stroke: "#666",
fill: "#ddd",
strokeWidth: 2,
draggable: true,
name : name
});
// add hover styling
anchor.on("mouseover", function() {
document.body.style.cursor = "pointer";
this.setStrokeWidth(4);
layer.draw();
});
anchor.on("mouseout", function() {
document.body.style.cursor = "default";
this.setStrokeWidth(2);
layer.draw();
});
layer.add(anchor);
return anchor;
}
function buildTriangle(layer, points, name) {
var triangle = new Kinetic.Polygon({
stroke : "red",
strokeWidth : 4,
name : name,
draggable : true
});
triangle.a = buildAnchor(layer, points[0], points[1], "anchor");
triangle.b = buildAnchor(layer, points[2], points[3], "anchor");
triangle.c = buildAnchor(layer, points[4], points[5], "anchor");
triangle.was = { x : 0, y : 0 };
layer.add(triangle);
return triangle;
}
function drawTriangle() {
var triangle = this.get(".triangle")[0];
if ( !triangle.isDragging() ) {
triangle.setPoints([ triangle.a.attrs.x - triangle.was.x,
triangle.a.attrs.y - triangle.was.y,
triangle.b.attrs.x - triangle.was.x,
triangle.b.attrs.y - triangle.was.y,
triangle.c.attrs.x - triangle.was.x,
triangle.c.attrs.y - triangle.was.y ]);
} else {
var anchors = this.get(".anchor");
for ( var i = 0; i < anchors.length; i ++ ) {
anchors[i].setX(anchors[i].getX() + (triangle.getX() - triangle.was.x));
anchors[i].setY(anchors[i].getY() + (triangle.getY() - triangle.was.y));
}
triangle.was.x = triangle.getX();
triangle.was.y = triangle.getY();
}
}
window.onload = function() {
var stage = new Kinetic.Stage({
container: "container",
height: 200
});
var layer = new Kinetic.Layer({
drawFunc : drawTriangle
});
var triangle = buildTriangle(layer, [60, 100, 90, 100, 90, 140], "triangle");
triangle.moveToBottom();
// add the layer to the stage
stage.add(layer);
}
</script>
<style>
#container {
border: 1px solid black;
}
</style>
</head>
<body onmousedown="return false;">
<div id="container"></div>
</body>
</html>
jsFiddle: http://jsfiddle.net/Y9AtR/
I like #Tomalak's solution, here is mine:
http://jsfiddle.net/Y9AtR/2/
triangle.on('mouseover', function(){
triangle.a.show();
triangle.b.show();
triangle.c.show();
layer.draw();
});
triangle.on('mouseout', function(){
//if( not near triangle ) // add some logic so that they don't disappear right away, maybe use distance formula?
triangle.a.hide();
triangle.b.hide();
triangle.c.hide();
layer.draw();
})

Categories