Edit:
For whatever reason, this does not work with JavaScript. It won't let you set the background image multiple times. To fix this, I set the backgroundPosition property to calc(50% + translation_x) calc(50% + translation_y) instead of setting a transformation in the image. This seems to work (for now).
I am unable to set the "background-image" property of an element dynamically with JavaScript. I have had no issues doing so in the past, but my current script does not work at all. There are no error messages in the console, so I haven't the slightest idea what's happening.
I have created vector graphics for a game and I am attempting to move them across the screen using a group (<g transform = "translate(x, y)">). My script takes the current background of the element, background.style.backgroundImage, and replaces the line containing the group with the transformed version.
Now, if I run
background.style.backgroundImage = "url(\"" + transformed_background + "\")";
console.log(background.style.backgroundImage);
the old version of the background image (without transformations) is (predictably) displayed in the output and the image does not update. For instance, the output might be
… <svg xmlns=\'http://www.w3.org/2000/svg\' width=\'5000\' height=\'5000\'><g> …
while the output of
console.log(transformed_background);
is correct, and is something to the effect of
… <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"5000\" height=\"5000\"><g transform="translate(1327.0717423133253, 1819.0229885057504)"> …
The background of the element will not change, despite my best efforts. I have tried everything imaginable in an attempt to resolve this issue. I believed it might be caused by the loop it is in (with an interval of about 50 ms), but increasing the interval had no effect. This system works elsewhere in the script (where the background is set initially), and this segment uses the same method.
The script is available here, and the issue is on line 175.
Any information would be much appreciated.
Thanks!
The only thing I see is at line 177,
where you use the var from line 175.
You wrote there
document.getElementById("background").backgroundImage = "url(\"" + build_background + ")";
But if I am not wrong you change the background with js like that.
document.getElementById("background").style.backgroundImage = "url(\"" + build_background + ")";
So you forgot the style.
Btw why do you write the js in the html window and not in the window for js?
Related
I'm having trouble getting a website to work properly. It has numerous moving backgrounds and makes use of the css-invert filter.
Please have a look here:
http://epicstudios.de/blackwhite/
My problem is, that even average computers have problems processing the moving background, which is essential for the effect I want the site to have. I figured that the problem might be that I have too many divs with moving backgrounds, but since these Divs have different, inverted background-images, I can't just leave them transparent. Or is there a way to use the invert-filter without giving the div a background-image, so that it inverts the content of the div beneath it? I hope thats clear.
My script for the moving background looks like this:
(function($) {
var x = 0;
var y = 0;
var bg = $("body,.overlay,.center_cirlce,.left_circle,.right-circle,.enter,.enter_outer,.enter_inner");
bg.css('backgroundPosition', x + 'px' + ' ' + y + 'px');
window.setInterval(function() {
bg.css("backgroundPosition", -x + 'px' + ' ' + -y + 'px');
y++;
}, 70);
})(jQuery);
I would like to know, if there is a way to reduce the CPU usage or whatever makes it stutter that awfully, without having to give up the effects I'm aiming for... Or whether I have bad programming somewhere, which I should change to improve performance.
Thank You!
Well, animating background-position is always a bad idea. Especially on huge images like these. Try to put the background images in their own container and animate that container with transform: translate() or even transform: translate3d(). It'll be much much smoother.
If you want to do it with JS i can recommend Greensocks TweenMax Animation library. It's damn fast and it'll use CSS transforms when available and fall back if not.
And adding backface-visibility: hidden to your animated elements will smooth things out too. Problem is, it seems you're using backface-visiblity for that effect on your site. To make things perform better I'd advice you rethink your structure and use animations with CSS transform as much as possible.
See the following fiddle:
[edit: updated fiddle => http://jsfiddle.net/NYZf8/5/ ]
http://jsfiddle.net/NYZf8/1/ (view in different screen sizes, so that ideally the image fits inside the %-width layouted div)
The image should start the animation from the position where it correctly appears after the animation is done.
I don't understand why the first call to setMargin() sets a negative margin even though the logged height for container div and img are the very same ones, that after the jqueryui show() call set the image where I would want it (from the start on). My guess is that somehow the image height is 0/undefined after all, even though it logs fine :?
js:
console.log('img: ' + $('img').height());
console.log('div: ' + $('div').height());
$('img').show('blind', 1500, setMargin);
function setMargin() {
var marginTop =
( $('img').closest('div').height() - $('img').height() ) / 2;
console.log('marginTop: ' + marginTop);
$('img').css('marginTop', marginTop + 'px');
}
setMargin();
Interesting problem...after playing around with your code for a while (latest update), I saw that the blind animation was not actually firing in my browser (I'm testing on Chrome, and maybe it was firing but I wasn't seeing it as the image was never hidden in the first place), so I tried moving it inside the binded load function:
$('img').bind('load', function() {
...
$(this).show('blind', 500);
});
Now that it was animating, it seemed to 'snap' or 'jump' after the animation was complete, and also seemed to appear with an incorrect margin. This smacks of jQuery not being able to correctly calculate the dimensions of something that hadn't been displayed on the screen yet. On top of that, blind seems to need more explicit dimensions to operate correctly. So therein lies the problem: how to calculate elements' rendered dimensions before they've actually appeared on the screen?
One way to do this is to fade in the element whose dimensions you're trying to calculate very slightly - not enough to see yet - do some calculations, then hide it again and prep it for the appearance animation. You can achieve this with jQuery using the fadeTo function:
$('img').bind('load', function() {
$(this).fadeTo(0, 0.01, function() {
// do calculations...
}
}
You would need to work out dimensions, apply them with the css() function, blind the image in and then reset the image styles back to their original states, all thanks to a blind animation that needs these dimensions explicitly. I would also recommend using classes in the css to help you manage things a little better. Here's a detailed working example: jsfiddle working example
Not the most elegant way of doing things, but it's a start. There are a lot more easier ways to achieve seemingly better results, and I guess I just want to know why you're looking to do image blinds and explicit alignment this way? It's just a lot more challenging achieving it with the code you used...anyways, hope this helps! :)
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
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.
I have a swf with loads text into a Sprite that resizes based on the content put into - I'd like though for the ones that are longer than the page to have the browser use its native scroll bars rather than handle it in actionscript (very much like http://www.nike.com/nikeskateboarding/v3/...)
I did have a look at the stuff nike did but just wasn't able to pull it off. Any idea's?
The trick is to use some simple JavaScript to resize the Flash DOM node:
function resizeFlash( h ) {
// "flash-node-id" is the ID of the embedded Flash movie
document.getElementById("flash-node-id").style.height = h + "px";
}
Which you call from within the Flash movie like this:
ExternalInterface.call("resizeFlash", 400);
You don't actually need to have the JavaScript code externally, you can do it all from Flash if you want to:
ExternalInterface.call(
"function( id, h ) { document.getElementById(id).style.height = h + 'px'; }",
ExternalInterface.objectID,
400
);
The anonymous function is just to be able to pass in the ID and height as parameters instead of concatenating them into the JavaScript string.
I think that the JavaScript is fairly cross-platform. If you want to see a live example look at this site: talkoftheweather.com. It may not look as though it does anything, but it automatically resizes the Flash movie size to accommodate all the news items (it does this just after loading the news, which is done so quickly that you don't notice it happening). The resize forces the browser to show a vertical scroll bar.
I've never done it that way around but I think swffit might be able to pull it off.
I halfway looked at swffit but the height (and width sometimes but mainly height) would be dynamic - swffit let's you declare a maxHeight but that number would be constantly changing...maybe I could figure out how to set it dynamically. A great place for me to start though - thanks!
What I've mostly been using if for is to limit how small you can make a "fullbrowser" flash, and for that it works great.
Happy hacking!
(and don't forget to post your findings here, I might need that too soon ;))
SWFSize
See here for more details.
Intuitsolutions.ca