I'm building a parallax scrolling website (aren't we all) that amongst other things, reveals an image as the user scrolls.
I've done the 'reveal' by putting the image in the background, and placing a solid filled div on top. I then animate this div from 100% height to 0% height based on the scroll position, thus revealing the background image.
I'm doing this kind of thing multiple times and unfortunately I'm getting slow down.
Using Chrome's built in Timeline feature, I can see that most of this slow down is from Image Decodes. For the above reveal, it's re-Decoding the image every frame, which takes 22ms per image per frame.
Does anyone know when the browser needs to do Image Decode and when it doesn't? It seems obviously to me that it would need to if I resized the image, but not that it would need to when I just half cover the image?
Thanks for your help.
I've battled with this problem a lot also. As yet I have not found anything concrete and my proposed solution does not seem to work in ALL cases and I have not been able to ascertain why.
Anyway...
It appears that when you animate a solid element over the top of an image, chrome forces a recode of the image.
There are two things I have tried and for the most part they have been successful.
If you add -webkit-transform : translate3d(0,0,0) to the covering element, you should find most, if not all of the image decodes disappear.
If adding the above CSS to the covering element itself does not help, try adding it to the image instead, or indeed try adding it to both elements.
My understanding is that using the 3d css property pushing the image into its own composite layer which is cached and handled by the GPU rather than the browsers software renderer.
90% of the time I have found one of the above combinations successful. I hope it helps.
How do you animate the property? I think you may have plenty of alternatives to just animating the height (which is some sort of resize of the container).
Maybe it's less intensive to just 'clip' the background image with another element. I found a thread about it on StackOverflow with some suggestions. If you animate with javascript, unfortunately pseudo elements are no option...
Clip/Crop background-image with CSS
Related
I'm attempting to create an animation by moving a sprite image across a div. The sprite image contains each frame of the animation. The size of the "canvas" is 600px by 624px. Each frame on the sprite sheet is positioned every 600px and I'm moving the image 600px at a time.
Here is what I have so far...
voyced.com/crownacre/www/demo/sprite.html
I'm using the following JavaScript to move the image across the screen...
(function myLoop(i) {
setTimeout(function() {
defImg.css({
right: '-=600'
});
if(--i) myLoop(i); // decrement i and call myLoop again if i > 0
}, 60) // delay ms
})(114); // number of frames in the sprite
I've used several sprites all floated left as the total width of sprite sheets in 69000px, which causes even more issues if I use just one image! Hence why I have 4 at the moment.
So... The problem I am having is that the animation pauses briefly several times. It seems fine in Firefox (for me), but you notice it in Chrome and you can't miss it in IE.
It also always stutters every 16200px, making me think this is related to moving 1 sprite into the next on the screen.
Ideas please people?
Thanks in advance!
Have you tried using a sprite animation plugin?
http://www.spritely.net/
Does what you want, seems to run well on their demo.
Let me first say: The huge images you're trying to display as a sprite isn't exactly what sprites/animations are used for. You can better look into a real <canvas> solution (especially when looking at your animation), but that would require some more complex JavaScript skills.
Anyway, the problem with the stutter is because you're using several images that are all floated to the left, and position the slider with the right property. Each time another image needs to be displayed, a stutter can be noticed. This might have something to do with the browser engine, needing to paint the actual image (which is hard, since they're pretty big).
So, instead of using several images, you could also use one (take note, you might want to make this a .JPG or .GIF since they tend to be more compact than .PNG) and use actual CSS sprites with background-position.
Here's an example that uses your code, and one single image. Good luck!
Thanks again for the feedback guys. I used a combination of your tips that have helped me solve the issue I was having.
Spritely has helped immensely. Essentially it is doing the same as what #marcoK suggested, and adjusting the background-position property. This plugin also provides a fool proof way of controlling each frame of the sprite, as well as creating callbacks when it reaches a specified frame - awesome!
The other issue was the huge sprite. Mobile safari won't allow anything larger than 3MP so the max size I could make the image was 4800x624. I have 15 of these each as a separate animation that calls the next when it reaches the last frame. I was very sceptical about this working smoothly, but it does, and in all browsers.
I'm not overly happy with the number of request it makes but after optimising the pngs the file size isn't too bad if I add a pre-loader.
Really pleased with the outcome... http://www.crownacre.voyced.com/ and one more reason not to use Flash!
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.
There are many of us looking for a Javascript/CSS3 solution that can provide a windows7-like UI within a webpage, without using flash.
We need an Opacity mask, rounded borders, and a Blur...
We've got the Opacity and the rounded borders, now we need to be able to apply some Blur effects to a semi-transparent Div.
I tried the BlurFast effect from the Pixastic Library, but it only blurs the actual image, not the background we are seeing trough the image...
Basically, we want a Div to act as a Blur Mask over other contents...
If someone actually succeeded with this, i'll be glad to know its possible :) Thank you
http://t.co/fFLPKnzC
very good article on blur showing the state of the art
sadly "masking" parts of your page, that blur everything behind, is not that easy.
maybe the suggestions in ths blog help you out, as they are very straight forward and from a totally different direction..
therefor to embedd html within svg and use svg-filters on html elements later on
Thought this could be relevant: Aero
Personally, I think the fact that the author states this to be "In other words, one of the most messy and most ineffecient implementations ever"... AND that he can onlt get the effect to work in a single browser... to be extremely telling.
There is no way to do this efficiently or cross-browser at the moment.
The only way you might be able to do it is by using Pixastic to create the blurred image within Canvas, export as dataURI, then use that image as the background for your div. If the div moves, then the positioning of the background-image should move accordingly.
I'm trying to create several buttons that have 4-5 frames of animation in them, and rather than using the typical CSS method (where 1 image has both states, and CSS toggles between top and bottom), I was curious if anyone had an idea on how to do this with 4-5 frames rather than 2. Obviously CSS alone can't make this happen - but its becoming a real challenge to find ANY info on this. Because the images have individual animation, I can't simply use the opacity to fade into the new image, it has to contain all 4-5. Any help would be much appreciated!
Zach
have a look at k10k and see how the buttons in the top are done: animated png's and animated gifs ;)
The only way I can think of to do this without JavaScript would be for the hover state to load an animated GIF for the background image. Otherwise, you'd have to use something like jQuery to animate the background-position property instead.
for this you'll need to use an animated GIF. if you don;'t have a animated GIF creation tool installed, either use Photoshop, which may be massive overkill, or one fo the free tools like GIFted motion
A very non-traditional frowned upon way this can be done is to...
-Animate them as a flash object. Export the xml/flash and imbed it into the htm
I want take a section of a picture, for example the middle of a picure, and repeat only that section in the background of a div. Is this even remotely possible? I suppose I could do this in javascript, but that would be messy.
In theory the answer to my question should be able to take a single pixel from a picture and repeat it in a line, or as a solid background.
Does anyone have any idea how I could do this in CSS?
You might be able to achieve this effect using the CSS3 border-image property.
Unfortunately, I am not aware of a way to do this sort of thing in CSS2. Also, I don't think that you can do this via CSS sprites, because sprites don't stretch parts of your image—they just allow you to show certain parts of the image.
Steve
Contrary to what some here have stated, depending on the image, you CAN do this with CSS/Sprites. But that isn't always going to be the case. It comes down to the image you want to repeat, it's height/width in relation to the sprite it exists on, the direction you want to repeat it, and the size of the container you want it to repeat in.
(source: sampsonresume.com)
This sprite could be repeated on the left 100px for use in a sidebar, while the other portions could serve as buttons and roll-over states in a navigation. with a small change, you could make the repeatable portion horizontal.
If you want a cross-browser solution, then currently you're out of luck, especially if you want a CSS-solution.
The only way to do it with JavaScript would be through the canvas element, but that's not supported by IE.
CSS cannot do this. You can however do it server-side or by using SVG graphics or Flash. Note that doing it with a plugin would not technically be a 'background-image", you'd need to position your content over the top of it.