Showing objects after given time in x3d - javascript

I am trying to create an animation in x3d by gradually having more spheres appear in a model. Is there any possibiliy doing this within the x3d namespace?
I have tried using a javascript for loop to access every sphere and change it's transparency-attribute, but this leads to the old problem of having delays in javascript (effectively locking up my browser).
Ideally, I'd be looking for an attribute/tag allowing me to set the appearance time for each sphere. Alternatively, a javascript snippet starting the progress of having the spheres appear would suffice.
No code snippets here, this question is on more of a theoretical niveau.

The browser issue is probably due to the transparency attribute used on the spheres.
You can add a Switch node for every sphere that you have in the scene, with the whichChoice attribute set to -1, this indicating that the sphere is not shown (rendered). Then you can use a TimeSensor to trigger the visibility of any of the spheres by setting the whichChoice attribute of the Switch node to 0.
Note that each Switch node has only one children (choice) and that is the Sphere node.

Related

How can I move the camera in ThreeJS relative to perspective?

Question:
I've been working on a first-person maze game with Threejs. I have recently included DeviceOrientationControls to start moving it towards VR, but my previous system for moving the camera is separated from the camera. The camera no longer moves with the arrow keys.
How can I move my camera using arrow keys again while the camera is updated with DeviceOrientationControls?
If possible, how can I automate forward movement relative to the camera's perspective?
Update:
Alex Fallenstedt found a perfect example of what I wanted.
However, I have some questions;
How does the script make the camera move?
How can I simplify this and/or implement this into my work?
Resources:
How to control camera both with keyboard and mouse - three.js
Detecting arrow key presses in JavaScript
How to move camera along a simple path
How to control camera movement with up,down,left,right keys on the keyboard
Comparison:
Here's how it behaved prior (with working controls)
http://orenda.ga/stackoverflow/Nonvr.mp4
Here's how it behaves now (with Orientation)
http://orenda.ga/stackoverflow/VR.mp4
Note:
I've not included my script since I think that it isn't needed for this question. If you need it, please ask and I will insert it here.
To answer you two questions:
1) How does the script make the camera move?
Lets break the script up to its fundamentals. The script begins by adding a bit of state to determine if the user is moving forward.. This state changes when the user interacts with W,A,S,D. We add event listeners that will change this state when a user presses a key or lifts up from a key.. Now, every single frame that is rendered, we can add velocity in specific directions depending on the state of what keys are pressed. This happens here. We now have a concept of velocity. You should console log the velocity values in animate() and checkout how it changes as you move around.
So how does this velocity variable actually move the camera? Well, this script is also using an additional script called PointerLockControls. You can see the full script for PointerLockControls here. Notice how PointerLockControls' only argument is a camera. In order to move the camera, we need to use some nifty functions in PointerLockControls like getObject.. This returns the THREE.js object that you passed into PointerLockControls (aka the camera).
Once we can obtain the camera, we can then move the camera by translating its x, y, and z values by the velocity we created earlier in our animate function.. You can read more about translating objects with these methods in in the Object3D documentation.
2) How can I simplify this and/or implement this into my work?
This is probably the easiest way to implement first person controls to a camera. Everything else in the script example I shared with your earlier is for checks. Like if the user is in a threeJS object, allow them to jump. Or adding a concept of mass and gravity to always pull the user down after they jump. One thing that you might find very useful is to check if the pointer is in the browser's window!. Take the example, break it down to its simplest components, and build from there.
Here is a codepen example that shows you how to move the camera forward smoothly, without pointerlockcontrols, Start at line 53 https://codepen.io/Fallenstedt/pen/QvKBQo

Best/easiest way to make a 2D Chess board using Javascript/HTML5?

I am building a web based chess game in Javascript. I'm using the HTML5 canvas to display the board by drawing rectangles.
I am trying to implement the move logic. So when a chess piece is clicked, and then they click on an empty block, I want to move it. However, it is quite tedious using the canvas. I need to do the following:
Update my 2D grid of objects to reflect the change, I set the current
square to undefined and set the new square to the object being moved
clearRect(..) which I still haven't got to work
Redraw the image at the new position
Is there a better way?
Also, how do I deal with the 'double click'. I currently using a boolean that holds if the piece was pressed, and if it was and they click on an empty square I call the move function. Are there any other ways of doing this? Additionally, are there any tools for making it seem like the chess piece is being dragged?
I appreciate any help. Thanks guys.
Over the years I've written a lot of chessboards for HTML. In the end the simplest approach I think is:
Keep an array (either 1d or 2d, both have pros and cons) with just piece names (e.g. "wp"=white pawn, "bn"=black night, "--" empty). Nothing to be gained with an OO-approach or even a generic piece object.
Use one single canvas for the board, drawing the pieces on them with drawImage.
Write a function that just draws everything and call it when needed (don't bother erasing/drawing single pieces).
For piece dragging empty the square and create a separate dragged div containing just the dragged piece (redrawing the full board during drag can be slow for low-end mobile devices).
For dragging attach move and up handlers to the document and not to the canvas, so that you won't miss up events when the mouse is outside of the browser window.
Start dragging on mousedown and attach events for mousemove and mouseup. This will work both on computers and on mobile phones without having to handle specific cases. Always call preventDefault and stopPropagation.
Make full-page view with no overflow and handle resize yourself (you'll need to add some mobile-specific metas to stop phones messing up with the page).
HTML can really do impressive things with just 2d canvas, as an example see this 2d/3d chessboard. One single file less than 300k (200k zipped).
Easiest you say?
Using chessboard.js has to be the easiest way and it is 2D.
HTML
<div id="board1" style="width: 400px"></div>
JavaScript
var board1 = ChessBoard('board1', 'start');
It has very good documentation and tons of different examples (customization) and can be downloaded here.
Learning by coding -- Good for you!
Here are a few tips to get you started:
A reusable structure for your game:
Create a JS object for each of your chess pieces and save those piece-objects in an array.
// an example piece object
var blackKing={
player:'black',
pieceType:'king',
image:blackKingImageObject,
currentSquare:['E','1'],
isCaptured: false,
// etc...
}
// a pieces-array
var pieces=[];
pieces.push(blackKing);
Create a function that does all of these things:
clearRect the entire canvas,
redraw the chess board,
use the piece-array to redraw all the pieces onto the chessboard.
About click vs double-click vs dragging:
Yes, that's troublesome and requires special handling.
Many coders handle it this way:
Listen for mousedown and save that timestamp and initial mouse position.
If a mouseup plus another mousedown occurs quickly it's a double-click.
If a mousemove of more than a few pixels occurs then it's the start of a drag.
Otherwise, it's a single-click.

KineticJS clearRect equivalent

I am now entering Kinetic and it has made it far easier for me to draw on canvas. However, building a game app, I need to clear the rectangle on every animation request. They're controlled by an fps cap script, but still, there are about 50 updates per second.
Kinetic's .removeChildren() method not only clears the canvas, it deletes the canvas node from the DOM. Doing so not only makes DOM queries inconsistent by intervals of .02 second, but also drops my FPS rate by about 60% in comparison to stock HTML5 canvas handling on every machine I ran the game on.
Is there a KineticJS method for clearing the canvas in a manner such as clearRect()'s?
Edit:
I have also made sure it's not a problem on any other part of the program. Call stack doesn't overflow, the FPS drop is just due to DOM changing twice every .02 second.
Edit 2:
I have tried the following:
Ignore the layer before and create a blank rectangle to fill up the visible part of the canvas. It dropped my frame rate to about 14 FPS;
Use the .clear() method. It solved the DOM consistency problem but the frame rate got even lower than before.
It seems the only solution would be calling the default HTML5 clearRect() method, but that would mean creating the canvas element by hand (and possibly making Kinetic useless as a library for my app).
Edit 3:
As for the app, I've started using standard HTML5 canvas since I have a deadline. I'd still like to see a Kinetic solution though - it might be helpful in the future. It surprises me to see such a simple thing is so hard, if not impossible, in a popular library like KineticJS.
You can use layer.clear with a bounding area to clear just the "dirty" part of your layer.
// tell layer not to auto-clear on layer.draw
layer.setClearBeforeDraw(false);
// clear the "dirty" portion of the canvas
layer.clear(100, 100, 150, 150);
// adjust some animation values and
// just draw the element that has changed
myRect.draw();
You should try to create new Layer for example:
var newLayer = new Kinetic.Layer();
Or call this function:
Canvas.clear();
Kinetic makes it very easy to draw using layers, groups and shapes.
If your view is properly make of these items you can easily remove them and they will be removed from the stage.
Perhaps you need to rewrite you code to make it work better in kinetic.
if you think your code is properly written you can try (as a workaround) to create kinetic rectangle and fill it with whatever you want to simulate a clear.

HTML canvas events on overlapping objects?

If I have a canvas with a circle that changes color upon clicking on it, I can use a click event on the canvas element and handle the math for that (distance formula calculation <= radius). But what if I have two circles that overlap (like a van diagram), and I click in the middle of the two circles assuming that only the top circle should change color? If the math of the first circle is applied in this case, both circles would change color.
How would I deal with events in the canvas in terms of overlapping objects like the example above? With hopefully a fast/efficient algorithm?
You might want a framework like EaselJS that has a better api for what you're trying to do. Barebones canvas 2d-context doesn't provide much in terms of display-object / sprite behavior.
Responses above also mention some sort of list to represent layers. I don't think the implementation would be very difficult, just another condition to check for along with the radius.
Canvas isn't really like Flash or like a DOM tree whereby things have sort orders or z-indexes. Its a bit more like a flat rastered image and you have to rely upon other logic in your javascript to remember the sequence & stacking order of things you have drawn.
If you need this kind of interactivity I've always found it best to use a 3rd party library (unless it really is just a case of one or two circles which dont do much).
For interactive 'shape' based javascript graphics I would sugest Raphael.js or D3 which are actually more of SVG tools than a canvas one so maybe it's not for you but they are simple and cross-browser.
There's also processing.js (js port of Processing the Java lib) which feels a bit like flash and again can track all of the levels and objects. Theres a tonne of others but thats another topic.
If it's super simple the options might be:
Hold the co-ordinates of all shapes/elements composited on the canvas inside an object or array which also tracks their z-index/sort sequence, thereby letting you know whats on top.
Using the imagedata at the mouse coordinate of the click to establish what has been clicked
using multiple canvases composited on each other and letting the DOM do the work for the click events

trouble accessing objects inside of 3d cube

my link: http://dl.dropbox.com/u/7727742/playlistsite6/index5.html
I have a 3d cube using a variation of zachstronaut's demo
(link: http://www.zachstronaut.com/lab/galaxy-box/ ). It uses javascript, translate3d, scale3d, etc...
I've tried assigning different z-index values in the css file, but with no luck. I can access the objects outside the cube(you can see this with the hover effect), but not the objects inside the cube. I have a hunch it is because it's not doing a z-sort type of function like pre3d.js. I was wondering if anyone could offer some insight into where I should look for a solution.
Object coordinates are generated randomly, so you may have to refresh once or twice to get some objects that are inside the cube.
Thanks!
EDIT:
Only tested in safari and chrome dev
Webkit ignores z-indexes on anything that has translate3d defined, as it logically should. z-index is meant for a 2D world, it's like taking a bunch of paper and saying "this one is on top" -- you still have a flat surface. Unfortunately, if you want to be able to select one of the "stars" inside of your box, you're all but out of luck since you're using HTML nodes.
The normal way of doing this is using a click-map -- basically every object gets rendered twice. Once normally and once in a single color with no shading, etc. The 2nd rendering is never shown and is simply used to tell what the user clicked on. You get the color where they clicked and that color maps to a specific object. If you were using canvas, you would do it that way and just change the rendering order on the 2nd render.
Since you're using HTML nodes, you can't do that. You have a couple of options:
You can calculate which star is under the mouse on mouse-move based on viewport rotation and x/y/z position of the star
you can attempt the above method by overlaying an identical rendering without the cube and where the stars have a 0% opacity. Each star in your new rendering would map to a star in your existing one, and you'd have easy mouse-over detection.
Post the results! :)
First of all, I'm glad you found my demo interesting!
You're not going to have much luck trying to do a hover or capture a click event on objects inside of a 3D CSS3 cube for the exact same reason you wouldn't have much luck capturing a hover or click events on a div underneath another div... in HTML all the DOM events go to the top most DOM node. If one div overlaps another div, you can't click the one that is underneath. Everything inside the 3D cube is "underneath" another DOM node.
Things are further complicated because you're taking objects in 3D space and asking a user to interact with them on a 2D plane (the browser window) using a 2D input device (the mouse).
You could hide the faces of the cube so that they wouldn't block the user's clicks. You could do something like cwolves suggested.
Sorry I couldn't be more help... HTML kind of fails us a bit here. Welcome to the bleeding edge!

Categories