How do I clone a Kinetic.node without its children? - clone

I have a Kinetic.Stage and 2 layers: layer1 and layer2. I drag elements from layer1 to drop them in layer2, knowing that I made a design of a grid in layer2. I need to clone layer2 in its initial state, I mean without the shapes and images that have been drawn on it, just an empty grid.
document.getElementById('buttonAdd').addEventListener('click', function () {
var cloneLayer = layer2.clone({id: layer2.attrs.id + 1});
cloneLayer.draw();
stage.draw();
});
This code clones the whole thing: the layer and its children. What should I add, in order to remove children?
Things I tried and failed:
cloneLayer.destroyChildren();
var x = cloneLayer.getChildren();
x.hide();

"...just an empty grid". You can always create an empty grid with:
var newLayer=new Kinetic.Layer();
stage.add(newLayer);

Related

How to change the color of the polygons of an object during a collision in Three JS?

Hello to all I begin in Three js, I would like that when my box enters in collision of my Mesh that all the polygons which are inside my Mesh change of color
Current result
Demo
here is my function which allows me to detect the collision of my 2 objects
detectCollisionObject(box) {
const meta = this.getMetaByModelUUID(this.state.meshes[0].uuid);
meta.mesh.children[0].geometry.computeBoundingBox(); //not needed if its already calculated
box.geometry.computeBoundingBox();
meta.mesh.children[0].updateMatrixWorld();
box.updateMatrixWorld();
var box1 = meta.mesh.children[0].geometry.boundingBox.clone();
box1.applyMatrix4(meta.mesh.children[0].matrixWorld);
var box2 = box.geometry.boundingBox.clone();
box2.applyMatrix4(box.matrixWorld);
// //return box1.intersectsBox(box2);
console.log("Collision", box1.intersectsBox(box2));
}
Here is a picture of what I would like to have
example
I thank you for your answer

Display Mesh On Top Of Another | Remove Overalapping | Render Order | Three.js

I have 2 obj meshes.
They both have some common areas but not completely.
I displayed them both by adding them to screen ..
Just like a mesh on top of another.
But the lower mesh overlaps the top mesh
But what I want to acheive is the lower mesh should always stay below without overlapping and giving the space to the entire top mesh.
I went through this fiddle..Fiddle with renderorder
And I tried something with this like..
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
root.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
root.renderOrder = 1;
scene.add(root);
});
But I don't know for what reason the overlap still stays ..
I tried...
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
objLoader1.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
objLoader2.renderOrder = 1;
scene.add(root);
});
Then I tried going through this Fiddle .. Another Fiddle
But when I run in I get only the lower or the upper mesh .
But I want to see both without any overlaps..
var layer1 = new Layer(camera);
composer.addPass(layer1.renderPass);
layer1.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
layer1.scene.add(root);
});
var layer2 = new Layer(camera);
composer.addPass(layer2.renderPass);
layer2.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
layer2.scene.add(root);
});
I made the material depthTest to False
But Nothing Helped..
Can anyone help me achieve what I wanted ..
If anyone couldn't figure what I mean by overlapping see the image below..
And Thanks to anyone who took time and effort to go through and help me...
You can use polygonOffset to achieve your goal, which modifies the depth value right before a fragment is written to help move polygons off of eachother without visually changing the position:
material.polygonOffset = true;
material.polygonOffsetUnit = 1;
material.polygonOffsetFactor = 1;
Here is a fiddle demonstrating the solution:
https://jsfiddle.net/5s8ey0ad/1/
Here is what the OpenGL Docs have to say about polygon offset:
When GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT is enabled, each fragment's depth value will be offset after it is interpolated from the depth values of the appropriate vertices. The value of the offset is factor×DZ+r×units, where DZ is a measurement of the change in depth relative to the screen area of the polygon, and r is the smallest value that is guaranteed to produce a resolvable offset for a given implementation. The offset is added before the depth test is performed and before the value is written into the depth buffer.
You're experiencing z-fighting, which is when two or more planes occupy the same space in the depthBuffer, so the renderer doesn't know which one to render on top of the other. Render order alone doesn't fix this because they're both still on the same plane, regardless of which one gets drawn first. You have a few options to resolve this:
Move one of the beams ever so slightly up in the y-axis. A tiny fraction would give one priority over the other, and this distance may not be noticeable to the eye.
I saw your fiddle, and you forgot to add depthTest: false to your material. However, this will cause issues when depth-testing the rest of the shape, since some white is on top of the red, but also some red is on top of the white. The approach in the fiddle works only when it's a simple plane, not more complex geometries.
You can use a boolean operation that removes one shape from the other, like CSG.
I think you'd save yourself a lot of headache by using approach #1.

Adjusting small multiples sparklines

I have an heatmap that show some data and a sparkline for each line of the heatmap.
If the user click on a row label, then the data are ordered in decreasing order, so each rect is placed in the right position.
Viceversa, if the user click on a column label.
Each react is placed in the right way but I'm not able to place the sparkline.
Here the code.
When the user click on a row label, also the path inside the svg containing the sparkline should be updated.
And then, when the user click on a column label, the svg containing the sparkline should be placed in the correct line.
To place the svg in the right place, I try to use the x and y attributes of svg. They are updated but the svg doesn't change its position. Why?
Here is a piece of code related to that:
var t = svg.transition().duration(1000);
var values = [];
var sorted;
sorted = d3.range(numRegions).sort(function(a, b) {
if(sortOrder) {
return values[b] - values[a];
}
else {
return values[a] - values[b];
}
});
t.selectAll('.rowLabel')
.attr('y', function(d, k) {
return sorted.indexOf(k) * cellSize;
});
Also, I don't know how to change the path of every sparkline svg. I could take the data and order them manually, but this is only good for the row on which the user has clicked and not for all the others.
How can I do?
The vertical and horizontal re-positioning/redrawing of those sparklines require different approaches:
Vertical adjustment
For this solution I'm using selection.sort, which:
Returns a new selection that contains a copy of each group in this selection sorted according to the compare function. After sorting, re-inserts elements to match the resulting order.
So, first, we set our selection:
var sortedSVG = d3.selectAll(".data-svg")
Then, since selection.sort deals with data, we bind the datum, which is the index of the SVG regarding your sorted array:
.datum(function(d){
return sorted.indexOf(+this.dataset.r)
})
Finally, we compare them in ascending order:
.sort(function(a,b){
return d3.ascending(a,b)
});
Have in mind that the change is immediate, not a slow and nice transition. This is because the elements are re-positioned in the DOM, and the new structure is painted immediately. For having a slow transition, you'll have to deal with HTML and CSS inside the container div (which may be worth a new specific question).
Horizontal adjustment
The issue here is getting all the relevant data from the selection:
var sel = d3.selectAll('rect[data-r=\'' + k + '\']')
.each(function() {
arr.push({value:+d3.select(this).attr('data-value'),
pos: +d3.select(this).attr('data-c')});
});
And sorting it according to data-c. After that, we map the result to a simple array:
var result = arr.sort(function(a,b){
return sorted.indexOf(a.pos) - sorted.indexOf(b.pos)
}).map(function(d){
return d.value
});
Conclusion
Here is the updated Plunker: http://next.plnkr.co/edit/85fIXWxmX0l42cHx or http://plnkr.co/edit/85fIXWxmX0l42cHx
PS: You'll need to re-position the circles as well.

Multiple views/renders of the same kineticjs model

I am building a graph utility that displays a rather large graph containing a lot of data.
One of the things I would like to be able to support is having multiple views of the data simultaneously in different panels of my application.
I've drawn a picture to try and demonstrate what i mean. Suppose i've built the gradiented image in the background using kinetic.
I'd like to be able to grab show the part outlined in red and the part outlined in green simultaneously, without having to rebuild the entire image.
var stage1 = new Kinetic.Stage({
container: 'container1',
width: somewidth,
height: someheight
});
var stage2 = new Kinetic.Stage({
container: 'container1',
width: someotherwidth,
height: someotherheight
});
var Layer1 = new Kinetic.Layer({
y: someY,
scale: someScale
});
// add stuff to first layer here...
var Layer2 = new Kinetic.Layer({
y: otherY,
scale: otherScale
});
// add other stuff to second layer here...
stage1.add(mapLayer);
stage1.add(topLayer);
stage2.add(mapLayer);
stage2.add(topLayer);
at the point at which I've added my layers to stage1, everything is fine, but as soon as i try to add them to stage2 as well, it breaks down. I'm sifting through the source but I cant see anything forcing data to be unique to a stage. Is this possible? Or do i have to duplicate all of my shapes?
Adding a node into multiple parents is not possible by KineticJS design. Each Layer has <canvas> element. As I know it is not possible to insert a DOM element into document twice.

Raphael JS : mouseover/mouseout - problem with text-labels

I use Raphael JS to create an SVG-map with area's and textlabels. I want the area to highlight when you move the mouse over it.
I have this working now, but when I move the mouse over the label (in the center of the area) the mouseout-event for that area is triggered, so the area is unhighlighted again.
Is there any way to prevent this from happening, or a workaround ?
Create a rect with opacity set to 0 over the text and attach the event handlers on that rect. You can calculate the dimensions of the rect using getBBox() of the text.
Creating a set via Paper#set was the approach that worked for me. e.g.:
var st = paper.set();
st.push.apply(st, vectors); // `vectors`: my array of "hoverable" vectors
st.push(text); // `text`: my text vector for `vectors`
st.hover(function () {
text.show();
}, function () {
text.hide();
});

Resources