I am working on a panorama site and want to be able to add a text label that can be dragged to the right location. It is a spherical pano for what it is worth :) The next 4 paragraphs are good info in general, especially if you are stuck like I was, but the real question starts below the +++
I originally tried using the regular canvas trick, but the canvas was too large vertically. For instance if I wanted to say "Hello World" that might be 120px wide and 15px tall, but the "transparent" canvas would be 150px tall, which would overlap other text objects, but not the panorama.
The other issue was if I wanted it to be more than a single line, so for instance if I wanted to say "Did you see this cool stream?" that could be broken up into 2-3 lines. After playing with it I got wordwrapping to work on both the canvas and the sprites, but ultimately the canvas problem killed it for me.
After that I tried Sprites, which was better about not overlapping visually the other text objects, but the canvas size was still too large which created issues in the onMouseOver intersects where if it was too close together you were likely to start dragging the wrong one around, or if you just wanted to pan / tilt the camera around to look at the panorama you may inadvertently click on the oversized canvas.
I tried multiple times to get the TextGeometry working, but always got this error "THREE.TextGeometry: font parameter is not an instance of THREE.Font." till I finally found out the API changed in the latest version which made all the examples on the web useless. After I found out about the API change, I was able to get it working, here is a fiddle for anyone that needs it: https://jsfiddle.net/287rumst/1/
++++++++++
In my app, this previous example using TextGeometry works out just fine, but only when it is a single line. When I loop through and do the next line, it becomes an extra object that you drag around individually, which becomes a problem when I want to be able to click on it to edit the text, size, color and so on.
I am not sure what to do about the issue of dragging all lines as a group. I expected it to work when I added the group to the objects array, which is how I did it before with the lines, but it doesn't work, so I was thinking it would be great if it could be wrapped in a transparent box with the faces pressed against the side and then use the transparent box as the handle for dragging.
Here is the example of it working with wordwrap: https://jsfiddle.net/ajhalls/73dhu192/
Outstanding issues would be dragging the group, and causing it to face the camera from the center of the group, rather than the corner when being dragged. group.geometry.center() I would have thought would work, like it does when it is a single line, but again it has issues.
Related
I try to process dynamic 2d rainfields (comparable to this, just that I process the data dynamically and animate it).
Until now I found that the best fitting solution for my project is creating horizontal LineSegments, so I can process the data set line by line and give each LineSegment a color. I store everything I need in a BufferGeometry.
Now my problem is
that when I implement a zoom by simply reducing the z-index of the camera, the spaces between those lines become visible, because the lines dont become thicker.
I read that the linewidth-parameter of a LineSegment object is inaccessible on Windows so is there any other way I could try?
I'm trying to draw a tiled background using Javascript on an HTML5 canvas, but it's not working because shapes that intersect the edges of the canvas don't wrap around to the other side. (Just to be clear: these are static shapes--no motion in time is involved.) How can I get objects interrupted by one side of the canvas to wrap around to the other side?
Basically I'm looking for the "wraparound" effect that many video games use--most famously Asteroids; I just want that effect for a static purpose here. This page seems to be an example that shows it is possible. Note how an asteroid, say, on the right edge of the screen (whether moving or not) continues over to the left edge. Or for that matter, an object in the corner is split between all four corners. Again, no motion is necessarily involved.
Anyone have any clues how I might be able to draw, say, a square or a line that wraps around the edges? Is there perhaps some sort of option for canvas or Javascript? My google searches using obvious keywords have come up empty.
Edit
To give a little more context, I'm basing my work off the example here: Canvas as Background Image. (Also linked from here: Use <canvas> as a CSS background.) Repeating the image is no problem. The problem is getting the truncated parts of shapes to wrap around to the other side.
I'm not sure how you have the tiles set-up, however, if they are all part of a single 'wrapper' slide which has it's own x,x at say 0,0, then you could actually just draw it twice, or generate a new slide as needed. Hopefully this code will better illustrate the concept.
// Here, the 'tilegroup' is the same size of the canvas
function renderbg() {
tiles.draw(tiles.posx, tiles.posy);
if(tiles.posx < 0)
tiles.draw(canvas.width + tiles.posx, tiles.posy);
if(tiles.posx > 0)
tiles.draw(-canvas.width + tiles.posx, tiles.posy);
}
So basically, the idea here is to draw the groupings of tiles twice. Once in it's actual position, and again to fill in the gap. You still need to calculate when the entire group leaves the canvas completely, and then reset it, but hopefully this leads you in the correct direction!
You could always create your tillable image in canvas, generate a toDataUrl(), and then assign that data url as a background to something and let CSS do the tiling.. just a thought.
Edit: If you're having trouble drawing a tillable image, you could create a 3*widthx3*width canvas, draw on it as regular (assuming you grab data from the center square of data as the final result), and then see if you can't draw from subsets of the canvas to itself. Looks like you'd have to use:
var myImageData = context.getImageData(left, top, width, height);
context.putImageData(myImageData, dx, dy);
(with appropriate measurements)
https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas/
Edit II: The idea was that you'd have a canvas big enough that has a center area of interest, and buffer areas around it big enough to account for any of the shapes you may draw, like so:
XXX
XCX
XXX
You could draw the shapes once to this big canvas and then just blindly draw each of the areas X around that center area to the center area (and then clear those areas out for the next drawing). So, if K is the number of shapes instead of 4*K draws, you have K + 8 draws (and then 8 clears). Obviously the practical applicability of this depends on the number of shapes and overlapping concerns, although I bet it could be tweaked. Depending upon the complexity of your shapes it may make sense to draw a shape 4 times as you originally thought, or to draw to some buffer or buffer area and then draw it's pixel data 4 times or something. I'll admit, this is some idea that just popped into my head so I might be missing something.
Edit III: And really, you could be smart about it. If you know how a set of objects are going to overlap, you should only have to draw from the buffer once. Say you got a bunch of shapes in a row that only draw to the north overlapping region. All you should need to do is draw those shapes, and then draw the north overlapping region to the south side. The hairy regions would be the corners, but I don't think they really get hairy unless the shapes are large.... sigh.. at this point I probably need to quiet down and see if there's any existing implementations of what I speak out there because I'm not sure my writing off-the-cuff is helping anybody.
I'm currently working on an interface where I have a primary canvas that is 800x800 in size. At the top I've generated a bunch of icons. When a user mouses over the icons at the top, it matches his mouse's x and y coordinates to determine if he is currently hovering over any of the icons. If he is, I want to have a hover effect where a label appears next to the mouse with the name of the icon. As he moves, the label follows the mouse. If he leaves the icon or moves to a different one, the last one is cleared, and either there is no label displayed (if the user moved off all icons), or another label is displayed next to the mouse in the last one's place (if he hovers over another icon, the width of the label is a variable length depending upon the width of the text).
The process of ordering and displaying these icons all occurs within a separate object from the rest of the canvas renderings, thus I wouldn't exactly want to re-render that entire object to display the icons every time a mousemove event triggers, so I'm wondering if there's a way to draw to another "temporary" canvas' context and whether or not that could be easily cleared. as the mouse moves so there isn't any trails left behind on the primary canvas? Can anyone point me in the direction of an example like this or advise me on how I should go about accomplishing this sort of task?
Yes you can certainly draw it onto a temporary (in-memory) canvas. This is done a lot of various reasons, and yours may be valid (especially if you don't have any background that changes). But it may not be the easiest to implement, its hard to say without knowing more about your app.
There's a decent alternative you should consider: you could have two canvases that are 800x800 in size overlaid atop each-other. This can be useful for some applications (like games) where there is a background, foreground, and middle-ground that all have different moving parts (but the background parts move rarely, and foreground isn't always present, etc)
In the same way, you could "layer" your canvas app, with the icons being on one canvas, and the background and other parts of the app being on the other canvas.
I'm working on an app that displays a large image just about the same way as Google Maps. As the user drags the map, more images are loaded so that when a new part of the map is visible, the corresponding images are already in place.
By the way, this is a Javascript project.
I'm thinking of representing each tile as a square div with the image loaded as a background image.
My question: how exactly can I calculate what divs are showing, and when the tiles are moved, how do I tell when a new row of divs have become visible?
Thanks!
About calculating what divs are showing: learn the algorithm for intersecting two rectangles (the stackoverflow question Algorithm to detect intersection of two rectangles? is a good starting point). With that, the divs that are showing are the ones whose intersection with the "view window" is non-empty.
About telling when a new row of divs have become visible: you will probably need a updateInterface() method anyway. Use this method to keep track of the divs showing, and when divs that weren't showing before enter the view window, fire a event handler of sorts.
About implementation: you should probably have the view window be itself a div with overflow: hidden and position: relative. Having a relative position attribute in CSS means that a child with absolute position top 0, left 0 will be at the top-left edge of the container (the view area, in your case).
About efficiency: depending on how fast your "determine which divs are showing" algorithm ends up being, you can try handling the intersection detection only when the user stops dragging, not on the mouse move. You should also preload the areas immediately around your current view window, so that if the user doesn't drag too far away, they will already be loaded.
Some further reference:
Tile5: Tiling Interfaces
gTile: Javascript tile based game engine
Experiments in rendering a Tiled Map in javascript/html…
There's no reason to implement this yourself, really, unless it's just a fun project. There are several open source libraries that handle online mapping.
To answer your question, you need to have an orthophoto-type image (an image aligned with the coordinate space) and then a mapping from pixel coordinates (i.e. the screen) to world coordinates. If it's not map images, just arbitrary large images then, again, you need to create a mapping between the pixel coordinates of the source image at various zoom levels and the view-port's coordinates.
If you read Google Map's SDK documentation you will see explanations of these terms. It's also a good idea to explore one of the aforementioned existing libraries, read its documentation and see how it's done.
But, again, if this is real work, don't implement it yourself. There's no reason to.
I'm looking for a convinient way to create such an effect in a web application: i have some picture, which has not very high resolution, and i want it to appear as a cloud of particles in some random part of the screen, and then to move to it's position.
It's ok that i will lose some resolution (i don't think that 1x1px particles are nice ;) ).
I want to use silverlight/canvas or processing-js/canvas.
Any ideas?
Thx.
When your silverlight application loads the picture, what you can do is to split it into tiles. You use one object for each tile and you store the normal position for this tile (i.e. where it is originally in the picture). Then you give each tile a random position, and use a loop to move the tile in a line from the random position to its normal position. This appear as a cloud that resolves into the correct picture.
You can then play around with the size and number of tiles, and how they move to their correct position (you could have them slow down, or follow a curve instead of a straight line).