draw multiple lines and delete individual line - draw

I can draw multiple lines on the canvas; they are added to the layer using drawScene
dlayerA1.add(line);
line.getPoints()[0].x = mousePos.x;
line.getPoints()[0].y = mousePos.y;
line.getPoints()[1].x = mousePos.x;
line.getPoints()[1].y = mousePos.y;
moving = true;
dlayerA1.drawScene();
http://jsfiddle.net/user373721/xzEad/1/.
Is there a way to delete individual line?

Currently, you'll have to modify the points array like this:
line.getPoints()[0].splice(index, 1);
Since arrays are modified by reference, modifying the returned array modifies the "source of truth" points array attr

I assigned a unique id to each object and used the following to delet it when click on it:
r = r + 1;
var mousePos = stage1.getMousePosition();
rectA1 = new Kinetic.Rect({
x: mousePos.x - rOffset,
y: mousePos.y - rOffset,
width: 0,
height: 0,
stroke: 'red',
strokeWidth: 4,
id:"rectA" + r
});
rectA1.setListening(true);
myRect1[r] = rectA1;
background1.add(myRect1[r]);
//start point and end point are the same
rectA1.setX(mousePos.x - rOffset);
rectA1.setY(mousePos.y - rOffset);
rectA1.setWidth(0);
rectA1.setHeight(0);
moving = true;
background1.drawScene();
myRect1[r].on("click", function () {
this.remove();
});
My solution is based on this good answer: How to select an object in kinetic.js?

Related

Autodesk forge Markup extension markers position not matching x y z values

I am using the markup extension that can be found at https://github.com/wallabyway/markupExt and have not changed the code within the extension except setting this.size to a bigger value to make the marker easier to find
the actual rendering of the points works fine I just can't seem to place them in a specific position on the model, they just appear floating off in the middle of empty space.
Code to generate the point
var dummyData = [];
dummyData.push({
icon: Math.round(Math.random() * 3),
x: 129597.054373,
y: -27184.841094,
z: 44514.362733
});
window.dispatchEvent(new CustomEvent('newData', { 'detail': dummyData }));
I have tried feeding it values taken straight from a selected items properties and have also tried feeding it values taken from the following code (I have tried with and without the nominalise step)
function onMouseClick(event) {
var screenPoint = {
x: event.clientX,
y: event.clientY
};
var n = normalizeCoords(screenPoint)
var hitTest = viewer.impl.hitTest(n.x, n.y, true);
if (hitTest) {
alert(hitTest.intersectPoint.x + ' ' + ' ' + hitTest.intersectPoint.y + ' ' + hitTest.intersectPoint.z)
}
}
function normalizeCoords(screenPoint) {
var viewport = viewer.navigation.getScreenViewport();
var n = {
x: (screenPoint.x - viewport.left) / viewport.width,
y: (screenPoint.y - viewport.top) / viewport.height
};
return n;
}
The point moves when i change the x y z values but never to where I want them and am not sure where I am going wrong
Rather than the code found in the other extensions that uses the viewport to offset the point I seem to have fixed it by adding viewer.model.getData().globalOffset to the hit test intersection values

Add the same child shape to multiple objects

Ok so I have this vector shape:
my_shape.graphics.lineStyle(1, 0x00FF00, 1);
my_shape.graphics.moveTo(30, 38);
my_shape.graphics.lineTo(7, 38);
my_shape.graphics.curveTo(-1, 38, -1, 36);
my_shape.graphics.lineTo(-1, 3);
my_shape.graphics.curveTo(-1, -1, 3, -1);
my_shape.graphics.lineTo(35, -1);
my_shape.graphics.curveTo(39, -1, 39, 3);
my_shape.graphics.lineTo(39, 30);
Since I couldn't find how can I change color of the existing shape I created 3 of these with only difference in the color,is it possible to change color of the existing shape?
Is it possible to use that same shape in other classes? Or I have to create it again?
if(ability3.Locked == true && Ability.suma >= 5){
ability3.Locked = false;
ability3.addChild(my_shape);
ability4.Locked = false;
ability4.addChild(my_shapea);
ability5.Locked = false;
ability5.addChild(my_shapeb);
}
if(ability6.Locked == true && Ability.suma >= 10){
ability6.Locked = false;
ability6.addChild(my_shapeb);
ability7.Locked = false;
ability7.addChild(my_shapea);
ability8.Locked = false;
ability8.addChild(my_shape);
ability9.Locked = false;
ability9.addChild(my_shape);
}
When this first code (ability 3 to 5) runs all 3 childs show but when it comes to running other if command abilities 6 to 9 get their children but 3 to 5 got their removed..can i use multiple times the same shape?
I hope you understand what I meant xD
Thanks.
Here is an example of copying graphics from one object to another, and changing their color:
var newShape:Shape = new Shape();
newShape.graphics.copyFrom(my_shape.graphics);
var colorTrans:ColorTransform = new ColorTransform();
colorTrans.color = 0xFFFFFF;
newShape.transform.colorTransform = colorTrans;
A display object can only be on a single display list at a time. This means that if I do the following:
container1.addChild(my_shape);
container2.addChild(my_shape);
my_shape will end up on container2
Normally, you would create a class for this particular shape and instantiate it as needed, but judging from your code, I'm not sure that you're using OOP (please correct me if I'm wrong and I'll update my answer).
Having said that, you can always write a function that creates the shape you need using the color of your choosing:
function createShape(color:uint):Shape
{
var shape:Shape = new Shape();
shape.graphics.lineStyle(1, color, 1);
shape.graphics.moveTo(30, 38);
shape.graphics.lineTo(7, 38);
shape.graphics.curveTo(-1, 38, -1, 36);
shape.graphics.lineTo(-1, 3);
shape.graphics.curveTo(-1, -1, 3, -1);
shape.graphics.lineTo(35, -1);
shape.graphics.curveTo(39, -1, 39, 3);
shape.graphics.lineTo(39, 30);
return shape;
}
Now you can call that function whenever you need to create the shape:
if(ability3.Locked == true && Ability.suma >= 5){
ability3.Locked = false;
ability3.addChild(createShape(someColor));
ability4.Locked = false;
ability4.addChild(createShape(someOtherColor));
ability5.Locked = false;
ability5.addChild(createShape(anotherColor));
}
Where someColor, someOtherColor, and anotherColor each represent a different uint (color).

HTML5 / kineticJS getIntersection function implementation

I am learning kineticjs through tutorials provided at http://www.html5canvastutorials.com, things are good and easy to understand but, I am having issue in understanding the getIntersection function that i want to use among different objects while dragging to detect collision / overlapping objects.
As far as I have understood the example the getIntersection function expects a position and checks if its intersecting with any other object or not..
Though I got them but with some issues.
I am unable to accomplish this..
Below is the code that I have tried up to now..
<script>
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 500,
opacity: 0.5
});
var layer = new Kinetic.Layer();
var previous_position;
var new_position;
var collision = false;
var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
var yellowBox = null;
for(var n = 0; n < 6; n++) {
// anonymous function to induce scope
(function() {
var i = n;
if(n < 3){
y = 50;
x = i * 100 + i * 10;
}else{
y = 150;
x = (i - 3) * 100 + (i - 3) * 10 ;
if(n == 3){
x = 0;
}
}
var box = new Kinetic.Rect({
x: x,
y: y,
width: 100,
height: 50,
fill: colors[i],
stroke: 'black',
strokeWidth: 4,
draggable: true,
name: colors[i]
});
box.on('dragstart', function() {
previous_position = {
x: this.attrs.x,
y: this.attrs.y
};
});
box.on('dragend', function() {
if(collision){
//this.setPosition(previous_position);
layer.draw();
collision = false;
}else{
//this.setPosition(new_position);
layer.draw();
}
});
box.on("dragmove", function(evt) {
console.log(layer.children.length);
if(layer.children.length > 1){
console.log('dragging');
new_position = {x: this.attrs.x,
y: this.attrs.y};
// var posBL = {x: this.attrs.x,
// y: this.attrs.height + this.attrs.y};
// var posTR = {x: this.attrs.x + this.attrs.width,
// y: this.attrs.y};
var posBR = {x: this.attrs.x + this.attrs.width,
y: this.attrs.y + this.attrs.height };
var collisionTL = this.getStage().getIntersections(new_position);
// var collisionBL = this.getStage().getIntersections(posBL);
// var collisionTR = this.getStage().getIntersections(posTR);
// var collisionBR = this.getStage().getIntersections(posBR);
console.log(collisionTL);
console.log(collisionTL.shapes);
// if(collisionTL.length > 1 || collisionBL.length > 0 || collisionTR.length > 0 || collisionBR.length > 0){
if(collisionTL.length > 1){
console.log(collisionTL.shapes);
collision = true;
}else{ //if(collisionBR.length > 0){
collision = true;
}
// for(i=0; i < collision.length; i++){
// // console.log(collision[i]._id);
// }
}
});
if(colors[i] === 'yellow') {
yellowBox = box;
}
layer.add(box);
})();
}
stage.add(layer);
</script>
in the dragmove event you guyz can see I get the four corner positions of the dragging box {commented right now} and with this I was able to detect the overlap / collision but it has 2 issues:
1. very slow with only 3 objects in my test
2. if non of the corner points intersect it didn't fire the collision stuff {for this one box can be bigger so it can cover the other entirely}
I would highly apreciate if anyone can please help me accomplish this stuff..
[A] Any object dragging if by any mean overlaps any other object I want it to show collision.
[B] If possible make getIntersection to work on a particular layer group whichever is possible
[C] any other workaround beside kineticJS to accomplish the above task
Regards
Ok, the developer of KineticJS is working on improving the .getIntersections() function... or at least he said he is. But until the function is improved you have to make your own collision detection function. Assuming that your objects are rectangles or can be broken into a series of points you should go with something like this:
Create a function which determines if a point is in a shape (if the corner of a rectangle is inside another rectangle) like so:
function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
var oTop = objecty;
var oLeft = objectx;
var oRight = objectx+objectw;
var oBottom = objecty+objecth;
if(pointX > oLeft && pointX < oRight){
if(pointY > oTop && pointY < oBottom ){
return 1;
}
}
else
return 0;
};
then you can do a big loop which iterates through all objects in a layer to check collision, like so:
var children = layer.getChildren();
for( var i=0; i<children.length; i++){ // for each single shape
for( var j=0; j<children.length; j++){ //check each other shape
if(i != j){ //skip if shape is the same
if(checkCollide(children[i].getX(), children[i].getY(), children[j].getX(), children[j].getY(), children[j].getWidth(), children[j].getHeight()))
alert('top left corner collided');
}
}
}
the checkCollide function I provided only checks the collision for the top left corner on each shape, so you have to modify the function to check all corners, it's not a long rewrite, and there are plenty tutorials even here on stackoverflow which deal with 'bounding rectangles collision detection'
This may seem like it is a very heavy function, but surprisingly it is still faster than .getIntersections(). Also, you should throw in extra if statements so that the function doesn't run through all the checks all the time.
I created a game myself and was using .intersects() and was having a lot of slow down. I switched over to this type of 'simpler' collision detection and now my game runs around 60FPS. http://cs.neiu.edu/~tsam/physics/index.phtml (test/test) if you want to check it out. You can view page source to see how I structured the collision detection to be more efficient (such as in checkIntersectsGoal() function.

dynamically draw circle preloader error 1061 when in document class

I found a tutorial on how to make a dynamic unfilled and filled circle. that will take input from a slider to dertermine how much of the circle is drawn. I wanted to use this for a preloader. Unlike the author I would like to use it inside of a document class. I am getting
1061: Call to a possibly undefined method createEmptyMovieClip through a reference with static type document. and 1120: Access of undefined property circ1. The second is caused from the first. How would I get this to work in my document class? Thanks in advance!
//original code
// x: circles center x, y: circles center y
// a1: first angle, a2: angle to draw to, r: radius
// dir: direction; 1 for clockwise -1 for counter clockwise
MovieClip.prototype.CircleSegmentTo = function(x, y, a1, a2, r, dir) {
var diff = Math.abs(a2-a1);
var divs = Math.floor(diff/(Math.PI/4))+1;
var span = dir * diff/(2*divs);
var rc = r/Math.cos(span);
this.moveTo(x+Math.cos(a1)*r, y+Math.sin(a1)*r);
for (var i=0; i<divs; ++i) {
a2 = a1+span; a1 = a2+span;
this.curveTo(
x+Math.cos(a2)*rc,
y+Math.sin(a2)*rc,
x+Math.cos(a1)*r,
y+Math.sin(a1)*r
);
};
return this;
};
// empty
this.createEmptyMovieClip("circ1",1);
circ1._x = 100;
circ1._y = 150;
circ1.radius = 35;
circ1.onEnterFrame = function(){
this.clear();
var endAngle = 2*Math.PI*percentLoaded;
var startAngle = 0;
if (endAngle != startAngle){
this.lineStyle(2,0,100);
this.CircleSegmentTo(0, 0, startAngle, endAngle, this.radius, -1);
}
}
//filled
this.createEmptyMovieClip("circ2",2);
circ2._x = 220;
circ2._y = 150;
circ2.radius = 35;
/* code in tutorial i left out since its for a second filled in circle
circ2.onEnterFrame = function(){
this.clear();
var endAngle = 2*Math.PI*slider.value/100;
var startAngle = 0;
if (endAngle != startAngle){
this.lineStyle(2,0,100);
this.beginFill(0xFF9999,100);
this.lineTo(this.radius,0);
this.CircleSegmentTo(0, 0, startAngle, endAngle, this.radius, -1);
this.lineTo(0,0);
this.endFill();
}
}
*/
That code you got was made using Actionscript 2, and you're building it for Actionscript 3, so you have to either recode it to Actionscript 3 or compile it for AS2.

nested array does not work

I have the following problem: I have this multi-level array (nested array) which contains two rows of bitmapData. Row 1:360 rotated bitmapData objects; row 2: 360 rotated and colored bitmapData objects.
I try to access row 2 but that doesn't work. There are some mysterious error messages coming up ("TypeError: Error #1034: Type Coercion failed: cannot convert []#36d7e9e9 to flash.display.BitmapData. at BasicBlitArrayObject/updateFrame()").
Please can someone help me out with this problem? Thank you very much.
this function rotates and colors bitmapData; the rotated bitmapData is thrown into an array and the colored bitmapData is thrown into another array; a third array is used as a level array for nesting the other two arrays inside of it
public function createColoredRotationBlitArrayFromBD(sourceBitmapData:BitmapData, inc:int, offset:int = 0, color:Number = 1, $alpha:Number = 1):Array
{
tileList = [];
tileListSec = [];
levelArray = [tileList, tileListSec];
var rotation:int = offset;
while (rotation < (360 + offset))
{
var angleInRadians:Number = Math.PI * 2 * (rotation / 360);
var rotationMatrix:Matrix = new Matrix();
rotationMatrix.translate(-sourceBitmapData.width * .5, -sourceBitmapData.height * .5);
rotationMatrix.rotate(angleInRadians);
rotationMatrix.translate(sourceBitmapData.width * .5, sourceBitmapData.height * .5);
var matrixImage:BitmapData = new BitmapData(sourceBitmapData.width, sourceBitmapData.height,
true, 0x00000000);
matrixImage.draw(sourceBitmapData, rotationMatrix);
tileList.push(matrixImage.clone());
bitmapData = new BitmapData(matrixImage.width, matrixImage.height, true, 0x00000000);
bitmapData = matrixImage;
var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter (
[color, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, $alpha, 0]);
matrixImage.applyFilter(bitmapData, bitmapData.rect, point0, colorMatrix);
tileListSec.push(matrixImage.clone());
rotation += inc;
matrixImage.dispose();
matrixImage = null;
rotationMatrix = null;
bitmapData.dispose();
bitmapData = null;
colorMatrix = null;
}
return(levelArray);
}
creating my rotated and colored bitmapData
animationFrames = tempBlitArrayAsset.createRotationBlitArrayFromBD($bitmapData, 1, 270);
here I try to access the first row of my level array (that doesn't work; I can't access it)
tempEnemy.animationList = animationFrames;
tempEnemy.bitmapData = tempEnemy.animationList[1][tempEnemy.frame];
This function is for updating the frames
public function updateFrame(inc:int, row:int = 0):void
{
frame += inc;
if (frame > animationList.length - 1){
frame = 0;
}
bitmapData = animationList[row][frame];
}
}
this is a line showing how the updateFrame-function is used in my game (trueRotation is 0)
tempEnemy.updateFrame(tempEnemy.trueRotation);
I can't find anything wrong with createColoredRotationBlitArrayFromBD
var $bitmapData:BitmapData = new BitmapData(40,40,false, 0x7f7f7f);
var animationFrames:Array = createColoredRotationBlitArrayFromBD($bitmapData, 1, 270);
trace(animationFrames.length); // 2
trace(animationFrames[0].length); // 360
trace(animationFrames[1].length); // 360
var bitmap:Bitmap = new Bitmap();
this.addChild(bitmap);
bitmap.bitmapData = animationFrames[1][0]; // works..
That seems correct. Right? I get a red tinted bitmap.
The only 'bug' I see in the code you listed is in updateFrame
if (frame > animationList.length - 1){
frame = 0;
}
should probably be:
if (frame > animationList[row].length - 1){
frame = 0;
}
because animationList.length == 2
But everything else looks okay in the code you've provided, so without more code, i'm not sure there is anything to help.