How to undo the dots on this grid? - javascript

Refering to a live javascript playground at https://codepen.io/Maximusssssu/pen/MWrzpav?editors=1011 .When you click on the grid, it will put a triangle or a square depending on your liking using the buttons (triangle & square below the grid). However, I am trying to build an Undo function for both triangle and square. Can anyone offer me some guidance on this? Thank you for reading and have a nice day :) I use the code below to put square or triangle on the grid.
newDot.style.top = y + 'px';
newDot.style.left = x + 'px';
// Add the new element to the end of the body:
document.body.appendChild(newDot);

I would use Memento pattern to implement the undo functionality with the classes listed below.
Basically, the client (main function in my example) invokes const s = Grid.snapshot() method to take a snapshot of the current state of the Grid, and invokes History.push(s) to save the snapshot. When the client needs to undo the change, it retrieves the previous grid state, i.e. snapshot, by invoking const pre = History.pop(), and then feed the previous snapshot to the grid by Grid.restore(pre). The Grid.restore() method can internally invoke Grid.render() method to render the previous state of the grid, i.e. draw the previous set of dots.
Grid Class
Grid holds information about the grid, i.e. all the coordinates of the dots, shapes of the dots, etc.
Snapshot Class
Snapshot captures the state of the grid at some point in the past. Grid is responsible for producing an instance of Snapshot.
History Class
History saves all the previous states of the Grid by storing Snapshot objects. It it essentially a "stack", so it can push or pop a snapshot in a LIFO manner.
main
main function handle all the above objects to realize the required functionalities of the app.
UML Diagram
In order to implement the undo functionality separately for the square and triangle dots, I would tweak this design in such a way that it keeps track of two sets of previous states, one being the triangles and the other being squares. This would result in having two History objects, one recording previous states of square dots and the other recording those of triangle dots, as well as the Grid object producing separate snapshots for squares and triangles.

Related

How would I go about making a variable that allows me to toggle an object's visibility in Javascript

I am using the p5.js library to create Tetris. When someone gets a line clear (that is, a full line has been filled with Tetris blocks) then the tiles that made that line fill up should be removed/turned off.
What would be the best way to do this? For all visibility aspects of a tile, I use a show() function that draws a rectangle to show the tile. Should I add a variable to the object and check if that is true because executing the show function? Or is there a built-in method or function that makes removing an object easy? I can't seem to find anything like this online
It is hard to answer if we do not know how your tiles are represented in your program.
The method I recommend is to remove the tile from it's container structure altogether.
For example, if the state of your game is stored in a matrix, simply empty the cells that constitute a line. This way, your show() function should not be called at all.
Removing the tile from the container will work, but if its difficult then there is another way.
Have a variable to track whether the tile is being used and have its default be true e.g this.inPlay = true
Only update and show a tile if its inplay is true:
if (tile.inPlay == true) {
tile.update()
tile.show()
}
'''
If you want to remove it, just set its inplay to false
PS. a great tutorial for p5.js is on youtube (made by the coding train)
PPS. just search 'coding train p5.js tutorial' on youtube

How to create merged shapes based upon blurred originals

I'm using easeljs and attempting to generate a simple water simulation based on this physics liquid demo. The issue I'm struggling with is the final step where the author states they "get hard edges". It is this step that merges the particles into an amorphous blob that gives the effect of cohesion and flow.
In case the link is no longer available, in summary, I've followed the simulation "steps" and created a prototype for particle liquid with the following :
Created a particle physics simulation
Added a blur filter
Apply a threshold to get "hard edges"
So I wrote some code that is using a threshold check to color red (0xFF0000) any shapes/particles that meet the criteria. In this case the criteria is any that have a color greater than RGB (0,0,200). If not, they are colored blue (0x0000FF).
var blurFilter = new createjs.BlurFilter(emitter.size, emitter.size*3, 1);
var thresholdFilter = new createjs.ThresholdFilter(0, 0, 200, 0xFF0000, 0x0000FF);
Note that only blue and red appear because of the previously mentioned threshold filter. For reference, the colors generated are RGB (0,0,0-255). The method r() simply generates a random number up to the passed in value.
graphics.beginFill(createjs.Graphics.getRGB(0,0,r(255)));
I'm using this idea of applying a threshold criteria so that I can later set some boundaries around the particle adhesion. My thought is that larger shapes would have greater "gravity".
You can see from the fountain of particles running below in the attached animated gif that I've completed Steps #1-2 above, but it is this Step #3 that I'm not certain how to apply. I haven't been able to identify a single filter that I could apply from easeljs that would transform the shapes or merge them in any way.
I was considering that I might be able to do a getBounds() and draw a new shape but they wouldn't truly be merged at that time. Nor would they exhibit the properties of liquid despite being larger and appearing to be combined.
bounds = blurFilter.getBounds(); // emitter.size+bounds.x, etc.
The issue really becomes how to define the shapes that are blurred in the image. Apart from squinting my eyes and using my imagination I haven't been able to come to a solution.
I also looked around for a solution to apply gravity between shapes so they could, perhaps, draw together and combine but maybe it's simply that easeljs is not the right tool for this.
Thanks for any thoughts on how I might approach this.

AutoDesk View and Data API - return position of selected element

Question:
I've been using the AutoDesk View and Data API, and I've been curious to know if it was possible to return geometric information about a selected element. Ideally, I want the position, size, angle, type of shape, etc., of a selected element so that I could compare, for instance, two lines. I don't mind how this information is represented, so long as two shapes could be compared.
Objective:
If there was a line, such that (psuedo-representation):
(x1=0,y1=0),(x2=10,y2=0), a 2d straight line of length 10;
and another line, such that:
(x1=20,y1=20),(x2=30,y2=20), another 2d straight line of length 10.
Then I would be able to say that these two lines are similar from this information and deduce their angle. There would obviously need to be some indication of the type of entity that is selected also. That's the desired outcome of my question.
What I've tried:
So far, I've found several useful functions within Viewer3d.js, but none seem to return any data about the geometric position of a single selected shape:
Viewing.Extension.SomeExtension = function (viewer, options)
{
...
var shapeRenderData = viewer.impl.getRenderProxy(viewer, dbId);
var shapeFragmentData = viewer.impl.getFragmentProxy(viewer, dbId);
}
I already understand how to include the onSelect event, and that is left out for clarity of the question.
Both of these return a JSON object with properties of fragId, scale, quaternion and position - although with exception of fragId, these properties have null values.
Extra:
I am basing the extension I've created off of this GitHub tutorial from the AutoDesk team:
https://github.com/Developer-Autodesk/tutorial-getting.started-view.and.data/blob/master/chapter-3.md#Step5
Please note the fifth step includes code for the onSelect event I'm discussing, should you wish to recreate the question to help me solve this.
I've wrote that blog post about geometry snapping and selection commands. I think it should provide some elements of answer to your question:
Geometry snapping and selection commands with View & Data API

cesium - moving billboards

I am testing Cesiumjs to see if it can reflect a near-real-time expreience - for example: position of airplanes.
For that, I need to draw billboards and make them move - which I know is possible with cesium, just not sure how.
The code looks like this:
var billboards = scene.primitives.add(new Cesium.BillboardCollection());
var billboard = {
image : '/path/to/logo.png',
position : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)
};
billboards.add(billboard);
My question is how do I change the position of the billboard. I couldn't find ant documentation that would explain.
I thought doing:
billboard.position = ... //new position
but how will cesium know that I've changed the position attribute unless it somehow turns that reference into a observable object.
So how do I update the location?
Thanks.
Cesium does indeed listen for changes to billboard.position
(source code here), so it is correct behavior for apps to simply write a new position.
Note that you must write the whole position at once, meaning you may not write to billboard.position.x. Instead, keep a "scratch" Cartesian3 around (don't create a new one every animation frame at 60fps), write to the x,y,z properties of your scratch variable, and then assign your scratch variable to billboard.position. You can see in the source that the assigned value will be cloned into another pre-existing Cartesian3, so you may immediately reuse the scratch variable.
Here's an example:
// Just once at app startup. Don't call "new" at 60fps.
var scratchCartesian3 = new Cesium.Cartesian3();
var ellipsoid = viewer.scene.mapProjection.ellipsoid;
function onTick() {
// This is safe to call at 60fps.
billboard.position = Cesium.Cartesian3.fromDegrees(
lon, lat, alt, ellipsoid, scratchCartesian3);
}
Also note that your question and the above answer are focused on the "Graphics Primitive" layer of the Cesium API. Cesium has one higher layer, called the "Entity" API, that you can use if you want Cesium to handle the concept of user-selectable objects with pop-up descriptions etc. Here's a Sandcastle demo showing how to add a billboard as a property of an entity, instead of as a primitive. This allows you to add other properties to the same entity, for example a name, description, label, 3D model, etc, and have them all be controlled from the same position property, and have Cesium take care of popup descriptions. The position property is more complex for entities than for primitives, for example it can be constant or sampled. This allows entities to change position over time when the timeline is shown.

How to remove children from Layer without removing events associated to them - KineticJS

This question is related with one I asked before here. I'm currently using KineticJS 4.0.5 and I'm using multiple layers to display some shapes with different properties. Since I need to change the layers contents frequently I'm using removeChildren to remove a layer content, but it seems that removeChildren also removes the events associated to childrens. I would like to remove the layer childrens without removing their events because I may have to add them to the layer again.
I tried to set the layer.childrens attribute equal to an empty Array instead of using the removeChildren function. At first it seemed to work but on some cases, some weird things happen :/ Some shapes disappear and the only way to get them back is by setting their Z index. I think the main problem with this approach is related with some properties that must be reseted when contents are removed from the layer, but I don't know which are they.
I also tried to set the events again on each shape before drawing them but it doesn't work... They remain static on the screen... I event tried to use the setDraggable(true) on all shapes before drawing them but no luck... Do I need to create the objects again and apply the events to them again each time I want to redraw a layer with shapes I used before? Or would it be a good approach to store layers for each screen on my application? (I can have a lot of different screens, which would result in a lot of layers and only one would be displayed at a time...)
If you know a solution for this problem please tell me. I really need to solve this problem because it is very important for my project to be able to draw and redraw :/
Thank you!
Sounds to me that what you need is a way to visually remove objects from layers, but not actually delete them. Instead of using remove, try creating a new layer specifically for storage, where your main group within that layer is hidden. You'll want this group, and its layer, to be globals for easy access. Then, when you need to remove an object from view, use moveTo to move it into storage, and moveTo again to restore it to view.
var gObj = {storage : '', storageGroup : ''};
gObj.storage = new Kinetic.Layer();
gObj.storageGroup = new Kinetic.Group({name:'storage', x:0, y:0});
gObj.storage.add(gObj.storageGroup);
// assumes stage is already built
stage.add(gObj.storage);
gObj.storageGroup.hide();
function wareHouse(obj, group, store) {
// obj is an object to store when store === true, otherwise it's a name or id when retreiving, group is the group where object either is or needs to be, store is a boolean value
if (store) {
obj.moveTo(gObj.storageGroup);
} else {
// change the dot to pound ('.' = '#') if using id's
var box = gObj.storageGroup.get('.' + obj)[0];
box.moveTo(group);
}
var parent = group.getLayer();
parent.draw();
}

Categories