make objects push against each other in Raphael.js - javascript

me again with a very specific question about Raphael.js . What I would like to do is, that rectangles push against each other. Lets say I have following situation that each rectangle is side by side example picture and I let the one in the middle transform big:
r.click(function() { r.animate({ width: 100, height: 100 }, 500); });
how can I handle it, that the other ones move correctly away like the transformation.
I've tried it by transforming every by hand, but the problem is, my markup isnt that simple.
Thanks in advance.

Its difficult to know a specific answer without seeing any code and knowing what the markup issues or or how you can tie some maths into calculating the figures, it will likely be more complicated, but you may be able to calculate the amount moved by the rects compared to the new width of the original rect. This shows an example of one way you could maybe approach it... jsfiddle here http://jsfiddle.net/R8avm/3/
Edit: There's an updated fiddle which has some basic maths which can sort of figure the end x,y if you know which direction the cubes will be in. http://jsfiddle.net/R8avm/4/ It will need more complex stuff for more rects moving at different angles if thats needed.
<div id="container"></div>
paper = Raphael( "container",400,400);
var rects = [ [ 100,50,50,50, 150,50 ], //x,y,w,h,newx,newy
[ 50,100,50,50, 50,150 ],
[ 50,0,50,50, 50, -50 ],
[ 0,50,50,50, -50,50 ],
];
var newRects = new Array(4);
var r = paper.rect(50,50,50,50).attr({ fill: '#123' });
for (var a=0; a<rects.length; a++) {
newRects[a] = paper.rect( rects[a][0], rects[a][1], rects[a][2], rects[a][3]);
};
r.click(function() {
r.animate({ width: 150, height: 150, x: 0, y: 0 }, 500);
for (var a=0; a<rects.length; a++) {
newRects[a].animate({ x: rects[a][4] , y: rects[a][5] }, 500);
};
});

Related

Drawing faces over a country without overlapping borders in Three.js

My problem is that when creating faces for a country, there are faces which overlap the border.
Below is the image when all coordinates are used when creating the faces
image with all values (coordinates)
values_axis1 contains all the X coordinates [63.0613691022453, 65.1611029239906, 66.0721609548093, 68.8109022381195, 71.1822098033678..]
values_axis2 contains all the Y coordinates [34.37065245791981, 35.30003249470688, 38.11207931425505, 38.228254752215044..]
values_axis3 contains all the Z coordinates
for (var i = 0; i < values_axis1.length; i ++) {
object_geometry.vertices.push(new THREE.Vector3(values_axis1[i], values_axis2[i], values_axis3[i]));
object_geometry.faces.push(new THREE.Face3(0, i + 1, i));
}
Buy changing i++ to i+=2 we get this image of skipping some values
Arrow obviously shows the point zero where all triangles are drawn from.
Below is the part of code for that.
object_geometry.faces.push(new THREE.Face3(DRAW_FROM_HERE, i + 1, i));
This isn't per say a programming problem but more like a 'is there a algorithm for this'.
I could check for faces that collide with a border from point zero and skip them but then there would be holes and that would need to be filled by drawing from some other location. That could be done manually but doing that for all the countries in the world would take ages. I'm sure this could be done by somehow calculating where the holes are but I have no idea how that would be done.
If someone comes up even with a really bad solution performance wise it would be great! I'm planning on putting all the results in a file which could then be loaded and drawn since there is really no need to do this processing every time since the borders never move.
EDIT: ShapeGeometry was suggested and has been tested. I was wrong when I said that Z coordinates are not relevant but obviously they are due to the curvature of the globe.
Image of the shapeGeometry. 2d but otherwise perfect.
Question edited.
Edit: Solution
Thanks to #Gilles-Philippe Paillé for suggesting ear clipping. Found a great library https://github.com/mapbox/earcut
Here is updated code for others who might have the same issue.
function createVertexForEachPoint(object_geometry, values_axis1, values_axis2,
values_axis3) {
var values_x_y = []; // add x and y values to the same list [x,y,x,y,x,y..]
for (var i = 0; i < values_axis1.length; i++) {
values_x_y.push(values_axis1[i], values_axis2[i]);
}
// https://github.com/mapbox/earcut
var triangles = earcut(values_x_y);
// triangles = [37, 36, 35, 35, 34, 33, 32, 31, 30, 30, …] [a,b,c,a,b,c,a,b,c..]
// triangles contain only the verticies that are needed
// previously all possible faces were added which resulted in overlapping borders
// add all points, in this case coordinates. Same as before
for (var i = 0; i < values_axis1.length; i++) {
object_geometry.vertices.push(new THREE.Vector3(values_axis1[i], values_axis2[i], values_axis3[i]));
}
// go through the list and pick the corners (a,b,c) of the triangles and add them to faces
for (var i = 0; i < triangles.length; i += 3) {
var point_1 = triangles[i];
var point_2 = triangles[i+1];
var point_3 = triangles[i+2];
object_geometry.faces.push(new THREE.Face3(point_1, point_2, point_3));
}
}
I use a geoJSON which has 'polygon' and 'multipolygon' shapes. This code works for polygons atm but shouldn't need too much tweaking to work with multipolygons since the library supports also holes earcut(vertices[, holes, dimensions = 2]).
image of the result

Drawing an arc in phaser and apply tween to reduce its length within 5 second

Hey I want to draw a circle with phaser v2.3.0 and reduce it uniformly by applying tween on it.
It should look like this. But starting from a full circle perimeter(kind of hollow disk with some thickness at the perimeter) and reduce its perimeter uniformly withing 5 second.
You can take help with this example
As I am new to phaser so I am able to understand it or if you can give me simple example or solution, it would be better.
Thanks in advance
I got the answer
var GameState = {
update: function () {
this.graphics.clear();
this.graphics.lineStyle(6, 0xffffff);
this.graphics.arc(40, 90, 20, 0,
game.math.degToRad(this.angle.max), true, 128);
this.graphics.endFill();
}
create: function () {
this.graphics = game.add.graphics(0, 0);
this.world.bringToTop(this.graphics)
this.angle = { min: 0, max: 0 };
this.roundArcTween = this.add.tween(this.angle).to({ max: 360 }, 5000);
}
}

physics.js attractors, zero gravity and slowing down velocity

I've been experimenting with attractors in physics.js, rigging up a simple object in zero gravity, with an attractor at a point. This creates a great little 'gravity well' as can be seen here.
Where the simple square vector attracts towards a point, at 'x':200,'y':200, and then orbits around it. I'm looking for a way to turn this attractor into more of a gravity well, so that the objects attracted to it slow down over time and eventually settle static and stationary at the point of the attractor, until it was collided with or dragged with the mouse again. Is this a possibility?
Currently the object is created with:
var bodies = [Physics.body('convex-polygon', {
// place the center of the square at (0, 0)
x: 150,
treatment : 'dynamic',
cof: 0.01,
mass : 1,
y: 100,
vertices: [
{ x: 0, y: 0 },
{ x: 0, y: 200 },
{ x: 200, y: 200 },
{ x: 200, y: 0 }
]
})];
The attractor is created thusly:
var attractor = Physics.behavior('attractor', {
order: 0,
strength: 0.0005
}).applyTo(bodies);
attractor.position({'x':200,'y':200});
Affecting the strength of the attractor doesn't appear to help, it just changes the speed of the attraction and subsequent orbit.
I'm looking for a way, in effect, to add friction to the entire space, which I think will do the job in naturally slowing down the object so it ends up stationary at the attractor point. Not sure how to go about this with PhysicsJS.
There is the possibility to create your own Attractor-Behaviour: See this documentation.
If you don't want to that, you can set the option min of the attractor to the size of the polygon, so the forces stops, when the body is at the center of the attractor. Strength and order are optional options, so you don't need to specify them (According to the API). For example this should work for you:
world.add(Physics.behavior("attractor", {
min: 200,
pos: {"x": 200, "y": 200}
}));

HTML5 Canvas and Javascript issue drawing multiple animated sprites on same canvas

Sorry if the title is a little confusing, I didn't know what the best way to word it would be.
I'm working on a tile based java-script canvas game that uses sprite sheets and tile maps to create the world and objects in it.
I wrote a section of code to animate a coin to spin around. For a single coin this works fine, but adding more than one coin to the canvas will cause the animation to speed up beyond what's desirable.
Since the game will be adding coins as it progresses, after about 10 coins you probably won't be able to see the animation anymore.
Gif to show the issue:
I've tried multiple methods, even adding a frame delay to slow down the animation, but without the desired results.
Everything is on codepen http://codepen.io/TryHardHusky/pen/EjJdoK
But it's a little messy.
Code I'm using to animate the coin:
var coin = {
height: 32,
width: 32,
cFrame: 0,
mFrame: 8,
image: new Image(),
src: "http://s1.tryhardhusky.com/coin_gold.png",
draw: function(x, y){
coin.cFrame++;
coin.image.src = coin.src;
if(coin.cFrame >= coin.mFrame){
coin.cFrame = 0;
}
ctx.drawImage(coin.image, 32*coin.cFrame,0,32,32,x,y, coin.height,coin.width);
}
}
And to create a coin on the scene:
coin.draw(250,250);
coin.draw(218, 250);
coin.draw(186, 250);
This is a remake of my other pen: http://codepen.io/TryHardHusky/pen/rVbdmw
I had it working there, but was using another inefficient method to animate the coins. It's also very poorly optimized, Hence the reason for the new code.
Can anyone shine some light on what I'm doing wrong?
-- Edit --
Thanks to #canvas was able to fix it with:
var coins = [
[4,5,0],
[2,3,0],
[1,6,0]
];
.
for(var i = 0; i < coins.length; i++){
drawCoin(coins[i], i);
}
.
function drawCoin(cord,i){
coins[i][2] < 8 ? coins[i][2]+=1 : coins[i][2]=0;
var image = new Image();
image.src = "http://s1.tryhardhusky.com/coin_gold.png";
ctx.drawImage(image, 32*cord[2], 0, 32, 32, cord[0]*32, cord[1]*32, 32, 32);
}
Have you tried using this instead of coin?
draw: function(x, y){
this.cFrame++;
this.image.src = this.src;
if(this.cFrame >= this.mFrame){
this.cFrame = 0;
}
ctx.drawImage(this.image, 32*this.cFrame,0,32,32,x,y, this.height,this.width);
Also what you should probably do is have an array of coins, then simply add a new coin to that array then use a loop to draw out each coin and update each coin.
Create an array of coins (example code)
var coins[];
coins.push(new coin(xPosition, yPosition));
// Render coins
for(var i = 0; i < coins.length; i++)
{
coins[i].Draw();
}
I just forked your codepen,
This isn't perfect, but something like this (created an array, updated coin var to be a constructor and then added 3 coins to the new array)
CodePen : http://codepen.io/anon/pen/GJLwJw

Multiple shape fadout with Kinetic js produces a stack overflow

Hello Stackoverflow community
As I am trying to build a small game, i came to a problem.
Somehow, when i try to fade out multiple shapes, respectivly a group with the shapes in it, some of the shapes will not fade out or browser gets a stack overflow.
So as i tried out several hours to fix the problem i need your help.
Heres the link to a little fiddle i made: http://jsfiddle.net/hnBPT/
As you can see theres a function newFadeShapesOut() which needs the nodes that should be fade out and also the layer of the nodes.
It moves the nodes into a group and fades the group out. Somehow and sometimes, one or more shapes will not fade out or there occurs a fatal error.
Function for fadeout:
function newFadeShapesOut(shapes, layer, callback, speed){
if(typeof(speed) == 'undefined'){
speed = 1;
}
var g = new Kinetic.Group();
console.log(layer.getChildren().length);
console.log(shapes.length);
layer.add(g);
shapes.each(function(shape){
shape.moveTo(g);
});
console.log(layer.getChildren().length);
console.log(shapes.length);
var tween = new Kinetic.Tween({
node: g,
opacity: 0,
duration: speed,
onFinish: function(){
if(typeof(callback) != 'undefined'){
callback();
tween.destroy();
}
}
}).play();
}
PS: Google Chrome is recommend, firefox tends to crash.
Thank you for your help.
EDIT: Sorry i forgot about that, you can activate the script by clicking the red square.
There's some strange behaviour going on here. Look at my comments as I tried to rewrite your function:
function fadeShapesOut(layer, callback, speed) {
var children = layer.children;
//The layer here already shows some children have moved.
//2 children remain, 1 text and 1 rect.
console.log("LAYER");
console.log(layer);
//Again, children shows that there are only 2 children of layer at this point: Test 2 and Button Rect
console.log('CHILDREN');
console.log(children);
if(typeof(speed) == 'undefined'){
speed = 1;
}
var group = new Kinetic.Group();
layer.add(group);
children.each(function(child) {
console.log("CHILD");
console.log(child); //This spits out Test 1, Test 3 and the newly added Group. (Strange order???
child.moveTo(group);
});
//Since group is already added to the layer, you're all of layer's children to group, including group itself. Which is causing a never ending loop of references to group including itself - causing the stack overflow.
var tween = new Kinetic.Tween({
node: group,
opacity: 0,
duration: speed,
onFinish: function(){
if(typeof(callback) != 'undefined'){
callback();
tween.destroy();
}
}
}).play();
}
What's messing you up is that the group is being considered a child of layer (Even though it hasn't been added yet in the order of function calls, which is strange behaviour to me). So when you loop through the children of layer in the each function, you're trying to move group --> group which screws up the reference in a never ending loop.
I logged a bunch of things in my fiddle, so go ahead and take a look to see some of the strange behaviour I was talking about above.
Anyways, if your callback is going to destroy the layer, what is the point of moving everything to a new group in the function? That Group is messing your code up and I don't see the point of it if you're just going to destroy the layer.
Instead you can achieve the effect you want by just tweening the layer itself:
function fadeLayer(layer, callback, speed) {
var tween = new Kinetic.Tween({
node: layer,
opacity: 0,
duration: 2,
onFinish: function(){
layer.destroy();
tween.destroy();
}
}).play();
}
If you must stick with your original function format, then you can grab children by using names:
newsobj[n] = new Kinetic.Text({
nid: n,
x: 140,
y: ((n == 0) ? 294.5 : 304.5 ),
text: news[n],
fill: 'white',
fontFamily: 'Corbel W01 Regular',
fontSize: 11.26,
name: 'fadeThisAway'
});
button = new Kinetic.Rect({
x: 10,
y: 10,
width: 100,
height: 100,
fill: 'red',
name: 'fadeThisAway'
});
In my example, I used the name fadeThisAway. And then, using your old function:
function newFadeShapesOut(layer, callback, speed){
var shapes = layer.get('.fadeThisAway');
if(typeof(speed) == 'undefined'){
speed = 1;
}
var g = new Kinetic.Group();
console.log(layer.getChildren().length);
console.log(shapes.length);
layer.add(g);
shapes.each(function(shape){
shape.moveTo(g);
});
console.log(layer.getChildren().length);
console.log(shapes.length);
var tween = new Kinetic.Tween({
node: g,
opacity: 0,
duration: speed,
onFinish: function(){
if(typeof(callback) != 'undefined'){
callback();
tween.destroy();
}
}
}).play();
}
Instead of passing shapes through the function, just call
var shapes = layer.get('.fadeThisAway');
at the beginning of the function (you're passing layer through the function already anyways) to grab the children that are named fadeThisAway. (Note: This works because the group is not named fadeThisAway)
Working example and comments inside: JSFIDDLE
UPDATE
Okay so I made a basic example of the issue with layer.children
2nd JSFIDDLE
And it looks like that's just how the children of layer works. This proves that you definitely have to distinguish between shapes and group, because the group will always be considered a child of layer.
The naming method works to distinguish your shapes between layers by giving all shapes a common name that excludes groups.
After several attempts to bend projeqht's function to my way i finally did it!
Somehow, the collection shapes just updates itself when adding the group to the layer!
If i use an array instead, it works.
Hope it helps someone!
So here my solution which works like a charm.
function fadeShapesOut(shapes, callback, speed){
layer = shapes[0].getLayer();
if(typeof(speed) == 'undefined'){
speed = 1;
}
var g = new Kinetic.Group();
layer.add(g);
for(i in shapes){
shapes[i].moveTo(g);
}
var tween = new Kinetic.Tween({
node: g,
opacity: 0,
duration: speed,
onFinish: function(){
if(typeof(callback) != 'undefined'){
callback();
}
tween.destroy();
}
}).play();
}
If you have further questions, don't mind contacting me.

Categories

Resources