I need to display a very long area (without defined length) with many polygons (simple shapes - circles, squares, some text). Obviously I need only small fragment visible at a time. Main problems are efficient scrolling and handing mouse events. I write in GWT. Things i considered so far:
1) canvas. create a canvas with the size of visible area. Create buffer canvas larger then visible area. Render to the buffer (only changes - if something is changed in the visible area or new parts to the right/left during scrolling). And when required, render proper part of the buffer to visible canvas. This seems to work fast enough. But! I have to implement this smart buffering, decide which part needs to be rerendered and which not. And I need to remember all object to detect mouse clicks and mouseovers (and it should be some nice structure like interval tree or segment tree, as mouseover checks are very frequent - but this is already implemented in the browser, sounds like reinventing the wheel) - this is A LOT OF WORK!
Maybe there is something ready?
2) html (divs/images) - so, the idea is to render all elements with divs and images (images can be generated on canvas first, doesn't metter). Position them absolutely on a long div and use browser scrolling to scroll the div. Works until you reach the end of this long div and you need to reposition everything so there is more space to scroll (and this will freeze scrolling for some time). So maybe it would be possible to render in a second div in the meanwhile and then switch them.. It might work, but this sounds like a hack and it will probably have serious problems with multiple objects visible at a time. Plus for mouse events implemented in the browser.
3) SVG - I haven't tried, but I think I will run into the same performance problems as with html/divs (when scrolling to right/left)
Any ideas? Which approach is the best? Is there anything better? WebGL (it won't work in IE and porting to IE would be hard prob). How should I implement this?
You seem to understand the pros/cons. Canvas is faster, but it's lower level, so it's harder to code. DOM is slower but easier to code because of its event handling and object access. If DOM is too slow, you have to resort to canvas.
One possible compromise is to render the full canvas and clip it using overflow:hidden. That's what I did on a waveform display I am working on.
SVG should be easier than the DOM for shapes. Since SVG is not completely cross browser, you should use something like http://raphaeljs.com/
I would go with canvas as it's relatively fast.
As far as off-screen positioning, mouse events, and re-rendering — it could be all taken care of by using canvas library like Fabric.js. Take a look at the demos.
Event inspector demo & working with events tutorial might come in useful.
Off-screen (not) rendering is taken care of by default. Just position objects at off-screen coordinates and they won't be visible.
Related
I'm working with svg files and some processing.js code to create a homepage.
It has some animation and static elements but the idea is to have everything the same but with different colours - Like an alternative homepage. I want this alternative to "peek" through as the mouse moves around. Only a small area around the mouse.
Does anyone have any idea how to do that?
since it isn't an image file it's a bit tricky.
I tried doing it by using the an image and the "drawing" element of processing.js thinking it could paint the alternative homepage, however it repeats the image everywhere the mouse go and what i want is for everything to remain in the same position only show the different colours in that spot.
You might consider superimposing two versions of your site, the "top" one completely covering the "bottom" one (make sure all backgrounds are opaque). Then you could try applying an SVG mask to the top page, making it transparent at a specific area and causing the bottom page to shine through. You could modify the mask as the mouse moves.
The other way round - i.e. clipping the top layer - is also thinkable.
I see the risk that this approach is slow and not consistent across browsers - you'd have to give it a try. Speed may differ depending on whether you clip/mask the top or the bottom layer.
W3C SVG Clipping, Masking and Compositing specs
MDN page on clipping and masking
MDN page on applying SVG effects to HTML content
If one version of the page can be converted to other by swapping out colors, SVG filters might be an option as well.
I am trying to draw some guide lines via fabric.js like the online editor app on printio.ru.
So far, I placed 2 canvases with the same size in one page, the top one is to be a static workcanvas which used to draw some guide lines and the bottom canvas will contain some interactive objects. This seems to be how they do it in the page on the link above.
However, I can't work with those objects on the bottom canvas because the top canvas interrupts mouse events. Is there a way to let the mouse events to pass through to the bottom canvas? I am thinking of something like canvas.mouseenabled=false on the top canvas - is that possible?
I have thought of an alternative solution: place the guide lines and other objects in one single canvas. I don't like that solution because it adds things that I don't want to the bottom canvas and, in that case, I have to add some line instances instead of just draw line by context2d, which I think will give me low performance
Apply css-property
pointer-events:none
to upper elements, mouse events can through.
https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events
It will be work for modern browser.
http://caniuse.com/#feat=pointer-events
I have been trying to understand how they did those effects in http://artofflightmovie.com/ with no success so far. I am not even sure what to google for for help. Could any one ellaborate on it and perhaps put links to plugins\tutorials\other websites doing the same thing?
There is already a similar question, but it didn't help me a bit ^^
Custom scroll bar behavior in Javascript?
All of the answers here so far are spot on and cover various pieces of the execution. Joseph's post about how we 'contained' and 'maneuvered' the site are dead-on, and those mentioning jQuery accurately depict our heavy reliance on it :)
With that said, the other concept of moving along a non-linear path was probably the most difficult part. We literally used an Illustrator file that was setup like a piece of graph paper and drew a bezier path that reflected the movement we wanted from the scrollbar. Then we 'downsampled' the path by converting the curved lines into a bunch of straight lines that represented the curve (similar to downsampling audio waveforms) to keep performance/speed high. We took those coordinates, gave them to our designer, and he created a gigantic design file and literally designed each content section at the designated 'stop' points. Next we mapped each coordinate along the path to a percentage value of the scroll position. We stored these values in a JavaScript array. Lastly we wrote some JS functions that we pipe the scroll position through to determine how to offset the positioning of the site 'container'. (It basically 'tweens' between each coordinate allowing us very fine/precise values at any given scroll percentage) The scroll functionality is handled by a tall div that basically sets our document height to force a scrollbar, and we just read it's position during a Scroll Event and slide the container around to where it should be using the above mentioned functions.
The parallax effect is achieved by applying a percentage of the position offset (what we use to move the container around) and applying it to the sub-containers of the various content sections. This makes the subcontainers move slower or faster than the background, but on the same motion path.
Lastly, the little snowboarders and helicopters (which have CSS3 rotations in addition to x,y movement in some browsers!) are positioned by using a simliar array of 'start' and 'end' positions and tweening between them based on the scroll percentage.
I'll leave it at that to keep this from turning into a book, but I'd be happy to elaborate on specifics if you're interested.
Full disclosure: I was lead developer on the site. I'm not posting to 'toot my own horn' or anything like that, just to be helpful and provide assistance to a fellow tinkerer. I come here a lot to dig through and get insight from others. (many, many thanks to those who have helped us!) Also, shameless plug, but the film is breath-taking... go rent it if you haven't yet, you won't be sorry. :)
That's a pretty cool website ;)
Basically using some javascript you can detect how far a person has scrolled. Considering the amount of scrolling you can move the contents of your webpage around if their position is absolute.
There are a couple of jQuery plugins that allow you to do simular stuff although I'm not sure you can "scroll through" a sequence of coordinates.
Here are a couple of jQuery plugins that helps you get simular effects:
http://johnpolacek.github.com/scrolldeck.js/
http://johnpolacek.github.com/scrollorama/
http://demos.flesler.com/jquery/scrollTo
http://webdev.stephband.info/parallax.html
I just picked a couple I'm familiar with but there are many plugins that are alike.
edit:
Decided to add some more simular websites for your pleasure.
http://www.activatedrinks.com
http://www.beetle.de
http://www.nikebetterworld.com
the whole page is an "overlay" - a full width and height wrapper <div>. sort of how modal windows do their "full page shadow" effect and have a small div float inside. the whole page content is in that wrapper. the scroll path is a script. the script captures the body scroll and moves the contents of the div accordingly to the positions provided by the script. with a body long enough to be scrollable (which cannot be seen since the wrapper covers the whole page), it's as if you are scrolling sideways, upwards etc.
an analogy is a modal window. the wrapper is the full-page shade. the modal window is the content. and notice how modal windows stick to the middle? that's using a script to calculate it's position to stay in the middle by moving the modal window down, relative to the page's top. but in that website's case, they move in different directions.
It doesn't seem too complicated.
Using the .scroll(function() {}) in jQuery you listen for a scroll event. When triggered you set the position style (left, top) of the content div to give the appearance of moving sideways instead of down.
I guess you'll need overflow:none property on the div to prevent users from scrolling over the area you don't want them to see.
Sounds like a lot of effort for a clunky user interface in my opinion.
I need to make a interactive image gallery (or image slider) where some hotspots need be placed on. It has to be possible to click on those hotspots, to update a sidebar with the corresponding info. Some basic animation must also be possible on a slide or scene of the gallery.
Which setup would be the best solution.
I'm currently thinking about the canvas element, but the lack of specific events for drawn hotspots makes me doubt. EaselJS could be a solution though.
An alternative could be just using a regular javascript image gallery and place some fixed positioned hotspots on it.
This is actually a basic mvc-setup, I have the image gallery, hotspots and the sidebar.
Should I use a javascript mvc library like http://javascriptmvc.com/ or backbone.js
So my question actually is, what would be the best setup, with performance and some basic animation in mind?
Thanks.
other interesting links I found:
http://processingjs.org
http://raphaeljs.com
...
If you are displaying large images or expect users to have older browsers or browsers without current GPU acceleration then you should always use standard HTML4 elements to get this done. Using canvas is overkill and will cause you pain later on if you are not overly-experienced with it.
With DOM-based images you already have click events and can even use image maps to do the click-regions. With canvas you need to code your own click detection and map mouse position to a region to check for clicks.
All in all the simplest solution is usually the best one and for performance and ease of dev, canvas is not the way forward in my opinion.
I created a webgl animation using scenejs library (start it by clicking the button at the bottom left, note it plays music as well which you can't currently disable).
The problem I am encountering is that the floor/plane in the middle starts flickering and continues to flicker/blink through out the animation. Only towards the very end does the flickering lower and by the end stops completely (when the plane is about to end).
If I reduce the size of the plane to 10% of its size (from ~26000 to ~2600), it does not flicker at all.
I've tried adjusting the texture scales, has no effect. Lowering the fps didn't seem to have an effect either. Does WebGL have problems rendering large objects? Are there any work arounds this?
Could probably make the plane static, and have the texture of it moving, but it certainly would make a lot more things trickier, especially when more elements are added to it.
Setting the requestAnimationFrame had no effect, nor did removing the flash video. The only time it works fine is when the plane is significantly smaller, or when it is reaching the end of it.
Scene looks fine to me - what happens when you remove the Flash?
PS. Share this on a jsFiddle if you like..http://jsfiddle.net/
Also, what happens when you use the requestAnimationFrame option for the render loop?
Example here:
http://scenejs.wikispaces.com/scene#Starting