Fading PNG in Internet Explorer not working - javascript

I have a div which contains a PNG image, like this:
<div id="pop" class="pop_komm">
<img src="Graphics/komm.png">
</div>
I have a js code which is triggered on the "OnChange" event of a drop-list:
<select onchange="fadeIn('pop');" name="list" etc></select>
Here is the js code:
function setOpacity(eID, opacityLevel) {
var eStyle = document.getElementById(eID).style;
eStyle.opacity = opacityLevel / 100;
eStyle.filter = 'alpha(opacity='+opacityLevel+')';
}
function getElm(eID) {
return document.getElementById("pop");
}
function show(eID) {
getElm(eID).style.display='block';
}
function hide(eID) {
getElm(eID).style.display='none';
}
function fadeIn(eID) {
setOpacity(eID, 0); show(eID); var timer = 0;
for (var i=1; i<=100; i++) {
setTimeout("setOpacity('"+eID+"',"+i+")", timer * 2);
timer++;
}
setTimeout("fadeOut('"+eID+"')", 5000);
}
function fadeOut(eID) {
var timer = 0;
for (var i=100; i>=1; i--) {
setTimeout("setOpacity('"+eID+"',"+i+")", timer * 2);
timer++;
}
setTimeout("hide('"+eID+"')", 310);
}
The problem is that the opacity makes the PNG corners rough and black, and the transparency of the PNG is not working good at all.
I have tried using a pngfix, which does help IF the PNG has no "fade" effect. But as soon as I apply this fade effect I get the same problem.
Somebody must have solved this before, so please give me advice on how to solve it.
I googled and found this, but I don't really know what he means.
If you need more input let me know...
Btw, this works in all major browsers but IE6, 7 and 8.
Thanks

Yeah, setting alpha on a transparent PNG replaces the alpha channel completely with the opacity value, so the transparent parts come back into view.
As the page you linked says, you can put the alpha filter on an element that contains the PNG, which typically looks better, but that container element has to hasLayout. Add a height or zoom or whatever to the container to trigger IE's crazy hasLayout nonsense.
It's still not quite right, though, as you end up with each pixel having the minimum opacity of that pixel's alpha value and the set opacity, instead of multiplying the opacities. So the semi-transparent parts of the image end up with the wrong relative transparency. It can still look quite good as a fade-in effect, though.
Full multiplicative opacity can't be done in IE before IE9.

Related

Setinterval Animation sometime paused

I make an animation using sequence images. i run the images using setinterval function animation going fine but i dont know why it paused some time. i posted fiddle here look this fiddle you can able to notice this pause
Unwanted Pause Happen Here
myAnim = setInterval(function(){
$("#myImageHolder8").attr('src', nextImage5[u]);
u++;
if(u==nextImage5.length)
{
u=0;
}
}, 50);
Pls friends Help me.
You need to preload the image. Setting the image source inside the loop will definately cause a hick-up at one point as loading and decoding the image(s) may very well exceed 50 ms (cached or not). This will also cause the problem to appear randomly (and faster computers may not notice while slower one or slower connections may cause this more frequent).
Preload the images and the simply insert the loaded image into the container (a parent element) instead.
You can preload the images either by hiding them in DOM and use window.onload to start, or do it in JavaScript using an array and load counter.
An example of an loader:
Live demo
var images = [],
count = nextImage5.length,
len = count,
i = 0;
for(; i < len; i++) {
var img = new Image;
images.push(img);
img.onload = loader;
img.src = nextImage5[i];
}
function loader() {
count--;
if (count === 0) {
... start animation here...
}
}
and then in the animation loop do something like (sorry, my jQuery escapes me but you see the point):
$('#myImageHolder8').html('');
$('#myImageHolder8').append(images[u]);
Before setting the animation, make sure you preload your images first. So that the images are ready and loaded to display smoothly. You can use this preloader. And I would like to suggest that instead of changing the src of an <img> it is better to draw the image to a <canvas> then create a <canvas> for your next image.

Image background already changing, can I fit it to browser window and make fade in and out

Hello below is my JS code for a changing background image every 30 seconds. could somebody please advise me if there is a way to alter the code to fit the image to the browser window (100%) and also if there is any JS that I could use within this code to make the images fade in and out seemlessly and elegantly.
<script>
bgArr = ['images/bg1.jpg', 'images/bg2.jpg', 'images/bg3.jpg'];
bgCur = 0;
backgroundSwitch = function()
{
if (bgCur == bgArr.length) bgCur = 0;
document.body.style.backgroundImage = 'url('+ bgArr[bgCur++]+ ')';
}
window.setInterval(backgroundSwitch, 30000); // Switch every 30 seconds.
</script>
Thank you everybody
CSS3 introduced background-size: cover. This automatically sizes the background image to cover the entire parent element, either scaling it horizontally or vertically to fill.
See the entry on MDN.
background-size is supported by all major browsers.
Fitting to browser window should be simple enough. Depending on your browser requirements, you might be able to get away with background-size: cover in your CSS (see Albert's answer).
As for animating, you could either use CSS transitions and trigger them via JavaScript (generally by modifying the class) or use JavaScript to do it.
If using JavaScript, be sure to set a duration and then lerp (or some other method) between the states.
This is the general idea...
var img = document.getElementById("fade");
var fadeLength = 5500;
var opacity = 0;
var startTime = Date.now();
requestAnimationFrame(function me() {
// It's faded in, stop animating!
if (opacity >= 1) {
return;
}
opacity = (Date.now() - startTime) / fadeLength;
img.textContent = opacity;
img.style.opacity = opacity;
requestAnimationFrame(me);
});
jsFiddle.

change css on scroll event w/ requestAnimation Frame

I want to change the background color of in-viewport elements (using overflow: scroll)
So here was my first attempt:
http://jsfiddle.net/2YeZG/
As you see, there is a brief flicker of the previous color before the new color is painted. Others have had similar problems.
Following the HTML5 rocks instructions, I tried to introduce requestAnimationFrame to fix this problem to no avail:
http://jsfiddle.net/RETbF/
What am I doing wrong here?
Here is a simpler example showing the same problem: http://jsfiddle.net/HJ9ng/
Filed bug with Chromium here: http://code.google.com/p/chromium/issues/detail?id=151880
if it is only the background color, well why don't you just change the parent background color to red and once it scroll just change it to pink?
I change your CSS to that
#dad
{
overflow-y: scroll;
overflow-x: hidden;
width: 100px;
height: 600px;
background-color:red;
}​
I remove some of you Jquery and change it to this
dad.bind('scroll', function() {
dad.css('background-color', 'pink');
});
And I remove this line
iChild.css('backgroundColor', 'red');
But is the Red color it is important that won't work for sure http://jsfiddle.net/2YeZG/5/
I like Manuel's Solution.
But even though I don't get what you're exactly trying to do, I want to point out a few things.
In your fiddle code, I saw that you included Paul Irish's Shim for requestAnimationFrame.
But you never use it.
(It's basically a reliable setTimeOut, nothing else) it's from frame based animations.)
So since you just want to change some CSS properties, I don't see why you would need it. Even if you want transitions, you should rely on CSS transitions.
Other than that your code could look something like
dad.bind('scroll', function() {
dad.css('background-color', 'pink');
eachElemNameHere.css('background-color','randomColor');
});
Also you should ideally not use something like that if you can help it. You should just add and remove class names and add all these properties in your CSS. Makes it work faster.
Also, again I don't quite get it, but you could use the jQuery function to find out each elements' position from the top to have better control.
Your problem seems to be that you only change the background color of the elements which have already been scrolled into view. Your code expects that the browser waits for your code to handle the scroll event before the browser redraws its view. This is most probably not a guarantee given by the HTML spec. That's why it flickers.
What you should do instead is to change the elements which are going to be scrolled into view. This is related to off screen rendering or double buffering as it is called in computer games programming. You build your scene off screen and copy the finished scene to the visible frame buffer.
I modified your first JSFiddle to include a multiplier for the height of the scroll area: http://jsfiddle.net/2YeZG/13/.
dad.bind('scroll', function() {
// new: query multiplier from input field (for demonstration only) and print message
var multiplier = +($("#multiplier")[0].value);
$("#message")[0].innerHTML=(multiplier*100)-100 + "% of screen rendering";
// your original code
var newScrollY = newScrollY = dad.scrollTop();
var isForward = newScrollY > oldScrollY;
var minVal = bSearch(bots, newScrollY, true);
// new: expand covered height by the given multiplier
// multiplier = 1 is similar to your code
// multiplier = 2 would be complete off screen rendering
var newScrollYHt = newScrollY + multiplier * dadHeight;
// your original code (continued)
var maxVal;
for (maxVal = minVal; maxVal < botsLen; maxVal++) {
var nxtTopSide = tops[maxVal];
if (nxtTopSide >= newScrollYHt) {
break;
}
}
maxVal = Math.min(maxVal, botsLen);
$(dadKids.slice(minVal, maxVal)).css('background', 'pink');
});
Your code had a multiplier of 1, meaning that you update the elements which are currently visible (100% of scroll area height). If you set the multiplier to 2, you get complete off screen updates for all your elements. The browser updates enough elements to the new background color so that even a 100% scroll would show updated elements. Since the browser seldom scrolls 100% of the area in one step (depends of the operating system and the scroll method!), it may be sufficient to reduce the multiplier to e.g. 1.5 (meaning 50% off screen rendering). On my machine (Google Chrome, Mac OS X with touch pad) I cannot produce any flicker if the multiplier is 1.7 or above.
BTW: If you do something more complicated than just changing the background color, you should not do it again and again. Instead you should check whether the element has already been updated and perform the change only afterwards.

img attribute question re: IE --> won't display native width of images, reverts to 1px wide

This question regards my personal photography website. I use the following javascript to generate random image sequences each time the page is loaded or refreshed:
<script type="text/javascript"> $(function () {
var ar = [];
function returnRandomUnique() {
if ( !ar.length) {
for (var i = 16; i > 0; i--)
ar[ar.length] = i;
}
return '<img alt="photograph" class="picture" src="images/work_images/image_' + ar.splice(Math.floor(Math.random() * ar.length) ,1) + '.jpg" height="550" width=""/>';
}
// test
var str = [];
for (var j = 0; j <16; j++){
str[str.length] = returnRandomUnique();
}
$("#mainwork").append(str.join(''));
});
</script>
My html and css both validate (css has border radius warnings for three buttons) and the site looks good on everything except any version of IE. The problem is that the width of each image varies and cannot be specified (heights are all consistent at 550px --the site scrolls left to right.)
IE displays each image as a line, 550px high by 1px wide. I'd like to find a value that will allow the images to display properly or force IE to use a different html page that will have a fixed layout (remove the random image generator javascript) where I can add the values as appropriate. I don't know how to force one browser to use a different html file. Any help would be greatly appreciated. I'm not really familiar with javascript, but found this in a library and modified it as best as I could to fit my needs.
Thanks,
Matt
You should remove width="". If I remember correctly, that screws up IE.
Testing it here: http://jsfiddle.net/4pE7E/
In IE9/8/7, it does indeed cause the image to be 1px wide.

CSS opacity performance. Image fading

I'm trying to fade in-out my image for my photo gallery switching. All it's done in JavaScript which simply changes the opacity CSS value of the image element. This is really laggy (slow) on some computers - for example my laptop which isn't extremely powerful, but it's brand new (Asus Eeepc).
I was wondering if there's anyway I can fix this performance issue. I've seen demos of Canvas animation and HTML5 applied to images and they're really smooth on my laptop. I wonder if I can apply the same thing to my image fading feature.
Any ideas? How would I do this?
I quickly threw together an example of an image fading away using the canvas tag as requested: http://jsfiddle.net/6wmrd/12/ (Only tested in Chrome and Firefox)
I´m not sure if there is any performance gain though, but here is at least a very simple example of how it can be done. It should also be noted that this was done in 5 min so the code can be improved and optimized.
Otherwise, from my experience, if you have a solid background behind the image, I have found that it is sometimes smoother to fade an element over the image with the same color as the background.
Other ways you can improve performance could be to reduce FPS. If I´m not mistaken MooTools has 50 FPS as standard. However, reducing the FPS might influence the perceived performance.
Here is code that works for all browsers:
add to head :
/* ****************************
* updated for all browsers by
* Evan Neumann of Orbiting Eden on
* October 6, 2011.
* www.orbitingeden.com - evan#orbitingeden.com
* original version only worked for IE
*****************************/
<!-- Begin
/* *****************************
* * editable by user
* ***************************/
var slideShowSpeed = 5000; // Set slideShowSpeed (milliseconds) shared by IE and other borwsers
var crossFadeDuration = 5; // Duration of crossfade (1/10 second) shared by IE and other borwsers
var crossFadeIncrement = .05; //crossfade step amount (1 is opaque) for non-IE browsers
// Specify the image files
var Pic = new Array(); // do not change this line
// to add more images, just continue the pattern, adding to the array below
Pic[0] = 'images/dare2wear-427ED-e.jpg';
Pic[1] = 'images/PBW_3238EDSM-e.jpg';
Pic[2] = 'images/dare2wear-441_2ED-e.jpg';
/* ********************************
* do not change anything below this line
**********************************/
var f = 0; //index of the foreground picture
var b = 1; //index of the background picture
var p = Pic.length; //number of pictures loaded and in queue - this may increase as time goes on depending on number and size of pictures and network speed
//load the picture url's into an image object array
//used to control download of images and for IE shortcut
var preLoad = new Array();
for (i = 0; i < p; i++) {
preLoad[i] = new Image();
preLoad[i].src = Pic[i];
}
function runSlideShow() {//this is trigerred by <body onload="runSlideShow()" >
//if IE, use alternate method
if (document.all) {
document.images.SlideShow.style.filter="blendTrans(duration=2)";
document.images.SlideShow.style.filter="blendTrans(duration=crossFadeDuration)";
document.images.SlideShow.filters.blendTrans.Apply();
}
//increment the foreground image source
document.images.SlideShow.src = preLoad[f].src;
//if IE, use the shortcut
if(document.all) {
document.images.SlideShow.filters.blendTrans.Play();
}
//all other browser use opacity cycling
else {
var imageContainer = document.getElementById('imageContainer');
var image = document.images.SlideShow;
//convert an integer to a textual number for stylesheets
imageContainer.style.background = "url('"+Pic[b]+"')";
//set opacity to fully opaque (not transparent)
image.style.opacity = 1;
//run fade out function to expose background image
fadeOut();
}
//increment picture index
f++;
//if you have reached the last picture, start agin at 0
if (f > (p - 1)) f = 0;
//set the background image index (b) to one advanced from foreground image
b = f+1;
//if b is greater than the number of pictures, reset to zero
if(b >= p) {b = 0;}
//recursively call this function again ad infinitum
setTimeout('runSlideShow()', slideShowSpeed);
}
function fadeOut(){
//convert to element
var el = document.images.SlideShow;
//decrement opacity by 1/20th or 5%
el.style.opacity = el.style.opacity - crossFadeIncrement;
//if we have gone below 5%, escape out to the next picture
if(el.style.opacity <= crossFadeIncrement) {
return;
}
//wait 50 milliseconds then continue on to decrement another 5%
setTimeout('fadeOut()', crossFadeDuration*10);
}
// End -->
and add two elements to the body. The first is a container background element. I have used a div, but td, body and others should work too. The second is the foreground image. Lastly, within the <body> tag, add the onload function call
<body onLoad="runSlideShow()">
<!-- this is the main image background -->
<div id="imageContainer">
<!-- this is the main image foreground -->
<img id="SlideShow" name='SlideShow' width="324" height="486">
</div>
Luca one way to make it faster is to use hardware acceleration and webkit transforms. The problem is that different browser support this to different degrees. See
http://mir.aculo.us/2010/06/04/making-an-ipad-html5-app-making-it-really-fast/
hopefully in the not-to-distant futures support for hardware acceleration in the browser will be better.
Have a look at the front page of this site It's 5 images that fade in and out in rotation, pure css2, html4, javascript, and is cross-browser (as far as I am aware). The javascript is a bit hackneyed - written some time ago :) but it seems to be smooth enough. See how it is on your machine. If it lags, you could try with a slower update, say 150 or 200ms instead of a 100.

Categories