Paper.js use multiple moveTo commands on a path - javascript

I'm trying to do:
Using this code:
var p = new Path();
p.strokeColor = 'blue'
p.strokeWidth = 4
var size = 10
var o = new Point(100, 100)
p.moveTo (o.add ([-size, -size]))
p.lineTo (o.add ([size, size]))
p.moveTo (o.add ([size, -size]))
p.lineTo (o.add ([-size, size]))
But instead I get:
Apparently the second moveTo() is ignored. How could I make it work? I couldn't find anything in the documentation.

The solution in your case is to use CompoundPath instead of Path as you are intending to work on a group of paths.
There is a clue about that in the path.moveTo documentation:
On a normal empty Path, the point is simply added as the path’s first segment. If called on a CompoundPath, a new Path is created as a child and the point is added as its first segment.
Here is a sketch adapted from your initial code, demonstrating the solution.
var p = new CompoundPath();
p.strokeColor = 'blue';
p.strokeWidth = 4;
var size = 10;
var o = new Point(100, 100);
p.moveTo(o.add([-size, -size]));
p.lineTo(o.add([size, size]));
p.moveTo(o.add([size, -size]));
p.lineTo(o.add([-size, size]));

I ended up doing:
var s = 10 // size
var o = new Point(100, 100)
var p1 = new Path.Line (o.add ([-s, -s]), o.add ([s, s]))
var p2 = new Path.Line (o.add ([s, -s]), o.add ([-s, s]))
p2.strokeColor = p1.strokeColor = 'blue'
p2.strokeWidth = p1.strokeWidth = 4
Which is inelegant, but works. I have tried p1.unite (p2) but that also doesn't work.

Related

Why am I getting only a single circle in the canvas?

So I want my output something like this.
var circlePath = new Path.Circle(new Point(0, 0), 25);
circlePath.strokeColor = 'black';
var copy = [];
for(var i=0;i<=10;i++){
var j=100;
copy[i]= circlePath.clone();
copy[i].strokeColor = 'red';
copy[i].position = new Point(j, 0);
j=j+100;
}
Hence, I just used a variable to shift the copy to a new point. But it doesn't work and just displays a single circle.

PaperJS Rotate function displaying item two times

when i am trying to rotate the path it is displaying same item two times. can some one help me to prevent the item to display twice.
var center1 = ball1.position;
var center2 = ball2.position;
// Create a triangle shaped path
var triangle = new Path.RegularPolygon(new Point(80, 70), 3, 12);
triangle.id = Math.random();
triangle.fillColor = '#fff';
//triangle.selected = true;
triangle.strokeColor = '#00304A';
triangle.strokeWidth = 2;
triangle.position = path.position; **
var arrowAngle = 90 + ((center2.subtract(center1)).angle); ** triangle.rotation = arrowAngle;
I'm not sure why you're getting two triangles (there isn't enough code for me to see what the reason for that is) but the main problem is that rotation is a read-only property - you cannot set it. Try using rotate().
http://paperjs.org/reference/path/#rotate-angle

Use multiple materials for merged geometries in Three.js

I want to create a Pine using 2 meshes, 1 for the trunk and another one for the bush, this what I've done:
var pine_geometry = new THREE.Geometry();
var pine_texture_1 = THREE.ImageUtils.loadTexture('./res/textures/4.jpg');
var pine_geometry_1 = new THREE.CylinderGeometry(25, 25, 50, 6);
var pine_material_1 = new THREE.MeshBasicMaterial({
map : pine_texture_1
});
var pine_1 = new THREE.Mesh(pine_geometry_1);
pine_1.position.x = x;
pine_1.position.y = y + 25;
pine_1.position.z = z;
pine_1.updateMatrix();
pine_geometry.merge(pine_1.geometry, pine_1.matrix);
var pine_texture_2 = THREE.ImageUtils.loadTexture('./res/textures/5.jpg');
var pine_geometry_2 = new THREE.CylinderGeometry(0, 70, 250, 8);
var pine_material_2 = new THREE.MeshBasicMaterial({
map : pine_texture_2
});
var pine_2 = new THREE.Mesh(pine_geometry_2);
pine_2.position.x = x;
pine_2.position.y = y + 175;
pine_2.position.z = z;
pine_2.updateMatrix();
pine_geometry.merge(pine_2.geometry, pine_2.matrix);
var pine = new THREE.Mesh(pine_geometry, new THREE.MeshFaceMaterial([pine_material_1, pine_material_2]));
pine.geometry.computeFaceNormals();
pine.geometry.computeVertexNormals();
Game.scene.add(pine);
The Pine is correctly positioned as I want, however, the whole merged shape only uses 1 material instead of the 2 (the whole shape is covered by the 1st) and I want that each mesh has it's respective material when mergin both.
What I'm doing wrong? any idea?
After a long research I discovered that I was missing an extra parameter for the method 'merge' from the Geometry object, the last parameter is the index of the material that the mesh must have from the materials array, ex: 0 -> first material in 'materials' array... and so on.
So, my final piece of code looks like:
pine_geometry.merge(pine_1.geometry, pine_1.matrix, 0);
var pine_texture_2 = THREE.ImageUtils.loadTexture('./res/textures/5.jpg');
var pine_geometry_2 = new THREE.CylinderGeometry(0, 70, 250, 8);
var pine_material_2 = new THREE.MeshBasicMaterial({
map : pine_texture_2
});
var pine_2 = new THREE.Mesh(pine_geometry_2);
pine_2.position.x = x;
pine_2.position.y = y + 175;
pine_2.position.z = z;
pine_2.updateMatrix();
pine_geometry.merge(pine_2.geometry, pine_2.matrix, 1);
(Note the last numbers I add to each merge).
However, I want to clarify that this practice only works when we are dealing with various geometries that are from the same type, in this case, we're merging two CylinderGeometry, but if we wanted to merge for example a Cylinder with a Box AND add the MeshFaceMaterial, it wouldn't be recognized properly and the console will throw us 'Cannot read property map/attributes from undefined', nevertheless we can still merge both geometries but not providing multiple materials (that's a terrible mistake I made).
Hope this helps to anyone.
Here's a general function to merge meshes with materials, You can also specify if you want it to return it as a buffer geometry.
function _mergeMeshes(meshes, toBufferGeometry) {
var finalGeometry,
materials = [],
mergedGeometry = new THREE.Geometry(),
mergeMaterial,
mergedMesh;
meshes.forEach(function(mesh, index) {
mesh.updateMatrix();
mesh.geometry.faces.forEach(function(face) {face.materialIndex = 0;});
mergedGeometry.merge(mesh.geometry, mesh.matrix, index);
materials.push(mesh.material);
});
mergedGeometry.groupsNeedUpdate = true;
mergeMaterial = new THREE.MeshFaceMaterial(materials);
if (toBufferGeometry) {
finalGeometry = new THREE.BufferGeometry().fromGeometry(mergedGeometry);
} else {
finalGeometry = mergedGeometry;
}
mergedMesh = new THREE.Mesh(finalGeometry, mergeMaterial);
mergedMesh.geometry.computeFaceNormals();
mergedMesh.geometry.computeVertexNormals();
return mergedMesh;
}
var mergedMesh = _mergeMeshes([trunkMesh, treeTopMesh], true);

How to create a dynamic ellipse using paper.path object in raphael.js

I am a newbie to rapheal js & I need to create a dynamic ellipse only using paper.path() object.
Although we can do it using paper.ellipse(), but I need it to be done by only in path manner on demand of pre-exist code. I googled for it and only get the solution for circle2path().
Let me give a example to describe.
var paper = Raphael(10,10, 250, 250);
var start_x = 170;//this has to be dynamic
var start_y = 160;// so these are also
var r_x = 40;
var r_y = 35;
var ellipse = paper.ellipse(start_x,start_y,r_x,r_y);
// here instead of paper.ellipse, I need to use paper.path()
//for example I used path to create circle
var radius = 50;
var circle_path = "M"+ (start_x)+ (start_y-radius)+"A"+ radius+radius+0+1+1+(start_x-0.1)+(start_y-radius)+ "z";
var circle = paper.path(circle_path);
Its working properly for circle. Is there any way to do with ellipse.
Thanks in advance.
Eureka.........
I got a solution from this question .
var paper = Raphael(10,10, 250, 250);
var start_x = 170;//this has to be dynamic
var start_y = 160;// so these are also
var r_x = 40;
var r_y = 35;
var ellipse = [["M", (start_x - r_x), (start_y)], ["a", r_x, r_y ,0, 1,1, 0,0.1 ],"z"];
var draw = paper.path(ellipse);
This is it, what I want. So we can create a function for it.
var ellipse2path = function(start_x,start_y,r_x,r_y){
return [["M", (start_x - r_x), (start_y)], ["a", r_x, r_y ,0, 1,1, 0,0.1 ],"z"];
};

How to draw circular segment using paper.js

How to draw circular segment using paper.js
I want to draw the circular segments as shown in the image. Each segment is independent and will later be used for interactive purposes.
I tried something like
//Temporary background circle
var keys = new Path.Circle(view.center, 130);
keys.fillColor = '#F1F1F1';
var home = new Path.Circle(view.center, 50);
home.fillColor = '#ee2a33';
var start = new Point(view.center.x, view.center.y-130);
var through = new Point(view.center.x-125, view.center.y-40);
var to = new Point(view.center.x-130, view.center.y);
var path = new Path.Arc(start, through, to);
path.strokeColor = 'black';
path.fillColor = 'green';
And it renders something like below
After several attempts, I came up with this. If anyone needs the same thing for whatever reason, maybe this will help.
//Creating keys
var arcOne = createSegment('#f1f1f1');
var arcTwo = createSegment('#666666');
var arcThree = createSegment('#333333');
var arcFour = createSegment('#666666');
var arcFive = createSegment('#999999');
var arcSix = createSegment('#000000');
arcTwo.rotate(-60, view.center);
arcThree.rotate(-120, view.center);
arcFour.rotate(60, view.center);
arcFive.rotate(120, view.center);
arcSix.rotate(180, view.center);
//center white
var center = new Path.Circle(view.center, 50);
center.fillColor = '#F1F1F1';
//Create Each segment
function createSegment(fillcolor){
//Segment One
var start = new Point(view.center.x, view.center.y-130);
var through = new Point(view.center.x-90, view.center.y-94);
var to = new Point(view.center.x-113, view.center.y-64);
var name = Path.Arc(start, through, to);
name.add(new Point(view.center.x, view.center.y));
name.add(new Point(view.center.x, view.center.y-130));
name.fillColor = fillcolor;
return name;
}

Categories