I understand that CSS3 animations do not work in IE. I was just wondering if there is a JavaScript workaround for this problem.
Here's a link to what I want to recreate in IE: http://animation.kashoo.co.uk/
Any advice would be great.
After a quick Google search I found a jQuery plugin that changes jQuery's standard $.animate() function so that it will use CSS3 transitions whenever possible:
$.animate-enhanced
edit:
After trying the above plugin on a site of mine, the site broke. I'm not sure if you will have the same problem or not, but here is my workaround:
You will need Modernizr.js
Basically, you check (with Modernizr) whether the browser supports a given feature, and then decide whether to animate with CSS3 or Javascript.
For example:
(Let's say you are animation an object to move to the right by 200px)
if(Modernizr.csstransitions) {
// use your appropriate browser prefixes
yourDomObject.style.transition = 'left 2s';
yourDomObject.style.left = parseInt(yourDomObject.style.left) + 200 + 'px'
} else {
var left = parseInt($(yourDomObject).css('left')) + 200 + 'px';
$(yourDomObject).animate({
'left' : left
},2000,'easeOutExpo');
}
Check out jQuery's animate functions:
http://api.jquery.com/animate/
There are many JQuery plugins that provide animations. Here's one that has a flip effect similar to the one you are looking for. http://lab.smashup.it/flip/
Related
I am trying to achieve a "crt-like" scrolling glitch effect using Javascript and CSS. I have come up with the following code which clones the content and applies clip to make it look like it scrolls while adding random horizontal offset.
function scanglitch() {
var e = $('#wrapper').clone().appendTo('#glitchcontainer');
var i = 0;
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css("z-index",200);
var interval = setInterval(function () {
e.css({"clip": "rect(" + i + "px,3830px," + (i + 15) + "px,0px)"});
e.css({"left": Math.round(Math.random() * 10) + "px"});
i+=4;
if (i > window.innerHeight) {
e.remove();
window.clearInterval(interval);
}
}, 40);
}
Fiddle (Click on the text to see the effect)
I am actually quite pleased with the effect, but the implementation is obviously a hack. As a result the performance is unacceptably low (chrome cpu usage spikes from 5% to 50% when the effect is triggered).
Could someone help me figure out a way to achieve this effect in a more elegant and less performance-heavy way?
UPDATE:
I have implemented your suggestions: Using translate instead of left, scrolling with translate instead of a js loop, calculations outside of the css tag and using requestAnimationFrame(). The code is nicer and more predictable now, but the animations are still very taxing.
New fiddle
You can try using requestAnimationFrame (it is available in almost all browsers). Seems to make a big difference in Chrome.
JSFiddle
EDIT
Here's a transition-only version, and while it doesn't even implement the jitter, it's useful for comparison. Surprisingly(?) it shows about the same, if not more, CPU usage. (You can check the Profile and Timeline tabs in Chrome)
CSS3 Transition-Only JSFiddle
Here's some information about why that should be expected. Essentially, CSS transitions and requestAnimationFrame work very similarly under the hood.
I would delegate as much as possible to css transitions. So instead of moving the clip with js in the interval callback, transition it from top to bottom (example of transitioning).
You could try something similar with the left property, there's no random easing function but maybe you could achieve something similar with one of the bounce functions. Maybe change the easing function with an interval that's less frequent than your current one.
Also, just by slowing the interval of your current solution you'd get visually ok results with less CPU usage.
Side-note: for a completely different route you can replicate your html in a canvas and apply some effects to that. Google has plenty of results for "canvas glitch".
Update: here's my version of your latest fiddle
I get about 10 % less cpu usage with it when comparing to yours. Key differences are:
uses a timeout instead of requestAnimationFrame. requestAnimationFrame is meant to keep framerate high and the animation smooth but we don't need that for the random offsetting. Timeout is also better than an interval since the loop function is quaranteed to finish before next iteration starts.
removed the transparent background, since transparency has a rendering cost
I'm working on a highly responsive website at the moment and I hit 2 areas where certain blocks of content need to move to others areas of the site. It would not be possible to do so purely with CSS. I suppose I could relatively reposition the blocks but as the dimensions change this isn;t really possible.
The option I am thinking of is, when a media query gets triggered, to then pull a block out of the page and append it in elsewhere where I need it.
I realise this is not ideal bit what I am wanting to ask is if this is a reasonable thing to so.
I know some of you may say reorder some of the markup but that is not possible. As stated above, I know falling back to javascript is not ideal but it would suit this and I don't particularly wish to duplicate content just so I can avoid the use of javascript.
Flexbox would be perfect but support is not where I want it to be currently for me to use that.
What do people here think? Any other solutions?
The right way is to listen to media queries using MediaQueryList:
var mql = window.matchMedia("(max-width: 320px)");
mql.addListener(function(event) {
if(event.matches) {
// Window width is less than or equal to 320, do something cool.
} else {
// Window width is more than 320, do something else.
}
});
The events will trigger when the query is either met or 'unmet'.
Alternatively, you can listen to a resize event, but note your function will get triggered for every new dimension. (Assuming jQuery in the code below.)
$(window).resize(function() {
if($(window).width() <= 320) {
// Window width is less than or equal to 320, do something cool.
} else {
// Window width is more than 320, do something else.
}
});
Like you said yourself though, using JS to make your layout responsive is generally NOT advisable. You can never assume all your users have JS enabled and all goes well.
I would rather see you solve this by restructuring your HTML and CSS. If the content layout has to change a lot, try outputting a block of content in two different places in your HTML and toggling visibility with CSS media queries (setting one to display:none; and the other to display:block;). You should be able to solve most responsive layout issues by rethinking your website structure.
Others looking for a solution may be interested in the Bootstrap Toolkit JS library available here: https://github.com/maciej-gurban/responsive-bootstrap-toolkit
Responsive Bootstrap Toolkit provides an easy way of breakpoint
detection in JavaScript, detecting changes in currently active
breakpoint, as well as executing any breakpoint-specific JavaScript
code.
The SASS module enables quick and simple styling for elements needing
different property values for each screen resolution.
Then you can do things like:
(function($, document, window, viewport){
// Listen to resize event
$(window).bind('resize', function() {
// Default 300ms poll delay
viewport.changed(function() {
// Debug
console.log( 'Current breakpoint: '+ viewport.current() );
// Trigger custom event
$('body').trigger('viewportChanged', [viewport.current()]);
}, 300)
});
// Register event listener
$(document).on('viewportChanged', 'body', function(event, current) {
console.log('Current breakpoint: '+ current);
}
})(jQuery, document, window, ResponsiveBootstrapToolkit);
You could check out some of the already available responsive design HTML boilerplates like Twitter Bootstrap or Zurb Foundation. Maybe their existing configurations satisfy your need.
I have a similar problem on two websites and i do:
JavaScript/jQuery with the window re size event and have breakpoints in JavaScript to. I then remove the item and append/prepend it where i want it to be.
On my other website i use Twitter Bootstrap which is very responsive and looks nice.
I would personally go with Twitter Bootstrap as its a nice grid system. If your site is very complex and cant be done using Twitter Bootstrap them capturing the window re size event is the best way.
$(window).resize(function() {
//Use $(window).width() and maybe some ifs/a switch to handle break points
if($(window).width()<700){
//Move it here
}
});
With CSS and JS it can be done :) You can clone the content to another section with jquery (append), then using media queries you can control what shows.
Here is what I do:
I do the appendTo:
$( $('.goto').html() ).appendTo('.mobile')
Here's an example I did:
http://jsfiddle.net/Riskbreaker/vkfWd/
This might not be what you are looking for (since its really not moving it but cloning the content )but this is the way I do it.
I would like to use webkit animation with #-webkit-keyframes but being able to dynamically modify the values on the rule, so that the animation is not static.
All the samples I found use a static #-webkit-frames, is there a way to customize with Javascript?
I had to create a new style rule in the loaded style sheets. Seems to work great in chrome 5.0.342.9 beta (at least)
var lastSheet = document.styleSheets[document.styleSheets.length - 1];
lastSheet.insertRule("#-webkit-keyframes " + newName + " { from { top: 0px; } to {top: " + newHeight + "px;} }", lastSheet.cssRules.length);
and then assign the animation name using element.style
element.style.webkitAnimationName = newName;
I wish I could credit for this, but here's a link to someone who managed to modify an existing animation, as opposed to creating a new animation.
http://gitorious.org/webkit/webkit/blobs/438fd0b118bd9c2c82b6ab23956447be9c24f136/LayoutTests/animations/change-keyframes.html
I've ran this to verify that it does, indeed, work.
EDIT
So that link is dead and I don't trust Gitorious to maintain URLS anymore so here's a link to a JSFiddle I created to answer a similar question: http://jsfiddle.net/russelluresti/RHhBz/3/
This contains script to find an existing animation, update its values, and assign it to an element to make the animation occur. I have tested this in Chrome 18 and Safari 5.1
First of all, I am not an advanced JQuery developer, however, I have been creating what I call Strips Menu with JQuery, you can see it here by clicking the Preview link on top:
http://jsbin.com/uwopu3/edit
When I click on a strip, it promptly shows the contents relevant to hovered strip but I need sliding effect something that has been done on this site:
http://jeemsolutions.com/
I tried giving the animate function a time of 1500, but still no sliding effect.
How do I give it sliding effect like that of jeemsolutions for which the link is provided above.
Thank You
You are using the animate function wrong. It takes the CSS properties you want to animate to as arguments, so try something like:
var w = $('#slide').width() - $('.bar').size() * $('.bar').width() + 10;
$(this).css('text-indent', '0px');
$(this).animate( {width: w}, 500);
I know this might sound wrong, but why don't you simply use jQuery Accordions? It does what you need, and is supported against different browsers and all that.
Cheers
The issue I am having is fairly complicated to explain. I have written up a javascript that displays an image slideshow, and it works fairly well, despite using up more resources than I would like
// imgArr[] is populated before
var i = 0;
var pageLoaded = 0;
window.onload = function() {pageLoaded = 1;}
function loaded(i,f) {
if (document.getElementById(i) != null) f();
else if (!pageLoaded) setTimeout('loaded(\''+i+'\','+f+')',100);
}
}
function displaySlideshow() {
document.getElementById(destinationId).innerHTML = '<div id="slideWindow"><img src="'+imgArr[i]+'" />' + '<img src="'+imgArr[i + 1]+'" /></div>';
setTimeout('displaySlideshow()',1000*3);
i++;
if (i >= imgArr.length - 1)
i = 0;
}
loaded(destinationId,displaySlideshow);
So, this script dynamically adds two images to a HTML element, and it is wrapped in a div.
The div is styled with the height and width of the image, with the overflow (the second image) hidden.
The second image is below the first, and the slideshow is meant to go from RIGHT to LEFT.
My inquiry is twofold:
1) Is there a more efficient way of doing this?
2) How would I animate the images? Would I need to put the second image on the right of the first with CSS somehow, and then set a timer to pull the images (via a style) leftward?
I really don't recommend rolling your own animation library. The Facebook Animation Library written by the wonderful Marcel Laverdet is simple to use and comes with a lot of tutorials to get what you want out of your slideshow. (Note: ignore the FBJS stuff, it's exactly the same even if you're using it on your own site.)
If you're not using a framework, I think you'll find a lot of pain ahead of you. If you still don't want to use a framework, at least find one that is liberally licensed, and take a look at the source code. Here's one, for example.
The basic theory is, yes, you set a timer that moves the image on some sort of interval, either fixed or based on some sort of mathematical equation (eg, sin, cos, etc). By setting these intervals close together, and making lots of them, you get an "animation" in javascript. Typically, you'd use some sort of absolute positioning, moving one element off the screen as the other moves on.