Resize flash object from the browser without flickering - javascript

I was wondering how to achieve the native scrollbar effect which TheFWA (thefwa.com) has managed to do pretty well (I am not a fan of Flex scrollbars).
I found this post (http://stackoverflow.com/questions/318675/how-can-i-create-a-flex-application-with-dynamic-height), and implemented the technique, as I am calling a JS function through ExternalInterface every time, when the flash object changes size. This JS function simply resizes the div which holds the flash object, which creates the native bars.
Unfortunately, when I resize quite rapidly (from 800 to 1800 height, for instance) the flash object simply gets warped for several milliseconds (as if it hasn't changed its size, but simply got pulled in all directions). After these milliseconds, things get back to normal, but the whole situation is really visually annoying.
Originally I thought that it's simply a timing issue, but after a bunch of attempts to set a delay, the effect was the same ... just delayed.
How can I resolve that? I know it's technically possible. Just take a look at TheFWA, and see how smoothly flash and the browser are communicating with each other to make the native scroll bars work, without any flickering, or mismeasurement

This is an issue that appeared since Flash Player 10 and is still happening up to FP 11 beta.
When you resize the DIV that contains the SWF, the SWF itself is resized, therefore you "ask" the player to redraw the content. But the thing is that this redraw creates this ugly flicker.
The workaround it to not resize the SWF DIV at all and to resize another empty DIV, so you force the browser to update the scrollbar.
At this point when you use the scrollbar it won't move the SWF DIV (as it is probably often a position absolute full-size flash site) but then you create a simple JS callback to send the scroll values to your application.
It may sound as a much greater effort but it is not much actually, and at the end you will create a more flexible way to manage your application.
You can check that in use here http://www.andrefelipe.com/
And the source code is at my framework https://github.com/andrefelipe/fabricaframework/blob/master/src/fabrica/external/Browser.as

The flash content on that site has fixed size. What they did is to put the swf file in a centered div. Something like this:
...header stuff...
<body>
<div id="flashContent" style="width:960px; margin:0 auto;">
...the flash content goes here...
</div>
</body>
The width of the div container should be the width of your flash movie.
If you want to resize the flash movie then take a look at swffit

That site isn't doing anything special, simply setting the height and width of the application and slapping it on the page - no resize is happening. If you simply employ the same technique (specifying a height for the app) then you will get the same results.
Am I missing something?

Related

Detect what percentage of viewport is obstructed by another window?

What I'd like to do, if it's technically possible, is leverage JavaScript (frameworks such as jQuery are totally fine, too), to determine what percentage of an inactive browser window might still be in view.
For example, in the image below, imagine I'm working on a project for CNN.com. In this scenario, I know I can use window.onfocus and window.onblur to determine whether the window marked as Background window is in focus or not.
[![enter image description here][1]][1]
However, I'm interested in measuring what percentage of the viewport/page for the Background window is visible to the end user, and/or what percentage of the page for the Background window is not visible. Or, an alternative approach could also be to simply determine whether an element (by ID) is in view on the Background window or it's obstructed by any foreground windows.
After extensive Googling and Stack Overflow searching, I'm not finding a solution for what I'm trying to achieve. This could obviously be due to technical impossibility, but I wanted to ensure I've left no stone unturned in troubleshooting.
The use case here is that I'd like to be able to pause videos and animations, etc. when a given element is not visible on the page -- not just when the window is not active at the moment, since users can often have windows arranged side-by-side, and might want to watch a video while multi-tasking. even though the window might be active at a given moment. Conversely, if a window is covered up, the desire here (for business purposes) is to pause the video, so we are not serving videos (or video ads) when a player is out of view.

Force a div to show up and overlay whatever is in fullscreen

I have a Chrome extension that inserts a menu into the page, but whenever any flash or html5 video player goes full screen, anything outside of the video player is invisible.
Could I have two objects in full screen at the same time (one over the other), or is there another way to do this? I would rather not have to insert the html specifically into different places on different websites, because of the large variety of existing video players. The solution should be universal for all video players.
EDIT:
Since then, a lot of the web has moved to using html5 instead of flash, so this has become a very possible thing to do on almost all websites.
Here was the code I ended up writing and using. Hopefully this will help someone:
document.addEventListener("webkitfullscreenchange", function(){//Whenever an element becomes or stops being in full screen
//first, grab the page's fullscreenElement
var fse = document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement;
if(fse){//if there is a fullscreened element
fse.appendChild(menu);//append the menu inside the fullscreened element
}else{//if nothing is in full screen
if(window.self !== window.top){//if we are in an iframe
menu.remove();//hide menu if we are in an iframe
}else{//if we arn't in an iframe
document.body.insertBefore(menu, document.body.firstChild);//show menu
}
}
});
This is not likely to be possible. The video player fullscreen implementation takes over the entire screen; you do not have a browser window to overlay on anymore.
It's not the same as going fullscreen in your browser, where you still have the normal browser window to work with.
edit: to expand further;
With any video player using Flash, this is absolutely not possible, because you have no chance of any HTML elements to overlay onto; the fullscreen is handled by flash itself, and you can't do anything with that.
With HTML5, from my testing it also seems impossible. I went to this sample page, edited the HTML in the dev tools to try inserting a div inside the video element, but it won't render.
If you had control over the pages, it might be possible to fullscreen a container div instead of the video itself, and then achieve what you want, but since you can't control the pages in question, that likely won't help you at all (unless you wanted to try replacing IDs/etc in-page, but even that wouldn't guarantee success; if the page JS already had handles on the relevant elements, replacing IDs wouldn't update those)
Unfortunately as #Collin Grady mentioned this is not possible since the browser takes care when you play a fullscreen video.
You can still simulate full screen tho! You could modify the size of the video to adjust to the size of the screen (or whatever size you require). By doing this you still have control on your elements and can show your menu on top of the video.
There is an article in CSS Tricks that could guide you on how to modify the dimensions of a youtube video. The writer of the article wrote a jQuery plugin too called FitVids.JS
By Simulating full screen you could show what you want on top.
I hope this helps

Repaint slowdown with CSS via Javascript in webkit browsers

I've been working on a slideshow script that uses CSS3 transitions, or jQuery's animate when they are unavailable. I've created a custom function to do the slide animations, which does so appropriately. Everything seemed to be working fine, but I've hit a major snag during testing.
For one reason or another, there is an large delay applying the jQuery CSS before and after the transition on large slideshows. For example, the slideshow in the link below is around 9900 pixels wide (container width, most of which is hidden). The container is maneuvered to display the appropriate slide, using CSS3 transition and transform properties. The delay occurs applying the CSS between lines 75 - 82 in the paste below. In particular, applying the 'transition' CSS causes the problem. Add the 'transition' CSS to the stylesheet (rather than applying it with JS), and delay disappears. This isn't really a solution however, because we only want to use CSS3 transitions on specific properties, that can vary (using 'all' in the stylesheet would transition some CSS that we don't want to animate, but change regularly).
Animation function:
http://pastebin.com/9wumQvrP
Slideshow Demo:
http://www.matthewruddy.com/demo/?p=2431
The real problem is with iOS, in which the slideshow (and even the browser sometimes) becomes completely un-usable. I can't pinpoint any errors, and have really exhausted my knowledge of debugging JS. I'm sure it is related to this section of the function after playing around a bit, and disabling CSS3 support within the plugin altogether removes the problem completely.
I'm completely stuck, and really appreciate any help anyone can give.
--- Edit ---
I've tried applying the CSS with native Javascript rather than jQuery's .css function. Same results, no better performance. Also worth noting that this isn't happening at all in Firefox, and seems to only be a problem with Webkit browsers.
Anyone with a solution, would happy to make a donation towards a few beers! I really cannot figure this out!
--- Second Edit ---
Ok, so been debugging and I can see that the slowdown is caused by the browser repaint cycle that is taking a very long time. Is there a better way to handle this that the way it is already doing? Positioning the element absolutely is a known way to reduce repaints, but that isn't really working because the slideshow is responsive. Absolutely positioning the slide images or the slides themselves causes it to collapse.
--- Third Edit ---
A day later, and I've made some progress. Adding 'transition: all 0s ease' to the elements stylesheet CSS has gotten rid of the repaint caused by adding the inline CSS transition property via the custom animation function mentioned in the original post. This causes a significant performance gain, especially when removing the inline CSS transition property when the transition itself has finished.
Good stuff! However, now there is still a slowdown when the inline CSS translate is being removed (that was used to create the hardware accelerated transition effect itself) after the transition, and the left positioning is being applied. When the two happen together, there is a slowdown.
Breaking them up into two separate tasks (the translate removed, then the left position added in a setTimeout with no time specified), again gets rid of the repaints = performance gain, and looks likes problem solved. But sometimes, the CSS transition property isn't get negated fast enough, and the translate removal gets animated. No good, and don't know where to look next to work around it.
I think the problem is you're loading HUGE images :)
They are too big for the container you have them in, so you scale them down, which is even more resource intensive.
Try resizing them.
First of all congrats for your debugging!
I have been working on the exact same stuff lately and found out that ios devices don't support a large number of images positionned in the same page. It causes crashes and the only solution I found was removing elements instead of just hiding them. The downside is that removing and appending elements causes lags so you have to do it cleverly, when your transitions are done. I thought the best way to go was keep 3 or 5 images in the DOM and replacing the rest with thumbnails of the images, resized to fit the original. When transitions are done, I'd just put the large images back into place...
Hope this helps you a bit on the ios problem at least...
After spending some time analysing your code TimeLine with Chrome Dev Tools, I believe there's some optimization you could do.
As far as I can tell, every single one of your 16 images gets fully repainted every time an animation is requested. This seems quite obvious to me, as there are 16 images in your example, and the Chrome Dev Tools reports 16 long "Paint" executions every time in hit "Next".
In my humble opinion, you should figure out a solution that considers only translating two images: the one you want to hide and the one you want to show. So, consider please, not moving the rest of the images and, instead, leaving them all side-by-side to the shown image.
One more thing, using scaled down images is probably making the paint cycles quite longer. Avoid them whenever you can.
Well, think I've managed to figure it out! Just so you know, original post links don't reflect the changes as I've done them on my localhost environment.
Absolutely positioning the slides container has fixed the problem that was occurring with repaint speeds after the transition had taken place (whilst applying CSS properties). Obviously taking them out of the DOM has done the trick, allowing painting to take place much more efficiently.
I originally didn't try this too much because I knew this would add a lot of work to the resizing functionality. I had originally intended to not resize at all in JS, and rely on percentages to do the dirty work. Absolutely positioning the container would cause the slideshow viewport to collapse, rendering the native resizing useless.
However, I was already having problems with sub-pixel rendering in other browsers anyway, so I guess it was time to bite the bullet and rely on fixed pixel values. I then used JS to handle the resizing, using the window resize event. All seems good, however the slideshow was still collapsed due to the positioning. Assigning height values wasn't working correctly, so was at a bit of a loss.
Thankfully, I came across a neat little trick of setting the 'padding-top' of the slideshow viewport to a percentage value, dynamically calculated (desired slideshow height, set in the settings panel for this script, divided by desired width). As padding-top percentages are relative to the width of the element, this did a great job of providing responsive height and correcting the viewport again (no longer looking collapsed).
Here is some info on using padding-top for responsive elements that maintain aspect ratio. Great little trick: http://f6design.com/projects/responsive-aspect-ratio/
All is good now, and things are working well in iOS and webkit browsers. Everything is extremely quick and working as it should. Four days later, and it is finally figured out. Not happy about having to resort to JS for resizing, but I guess it was always going to happen due to percentage inconsistencies between browsers. Lots of decimals = no good!
Thanks to all who tried to point me in the right direction. Definitely got me thinking, and learned a lot of debugging skills that I can use again to make sure transitions are performing well. Thanks again!
not sure if this helps or not but I noticed you use 3d translation - I would think a simple 2d translation would be enough especially since your third parameter is 0 and might accelerate the issue, also go with fewer images as Armel L. suggested, don't have an iphone to test though... alternatively, this is a solution I used before css3 but should still work move the element containing the images using javascript by modifying left (?and top - the demo only moves left and right though? without the transition effects) and this way you can fine-tune the refresh rate which I think might account for the slowdown... you can go as low as 18 fps without anyone noticing, might even be good enough with just 16fps
I had this when I was first designing a magazine carousel-style page device.
If you have a series of images within a long "tray", even if they are not within the viewport, they will still take up ram, and you can effectively have five or so before leaks and nastiness begin to happen.
What I found works is "hiding" them ... But make sure they take up the physical space necessary.
What I also found worked was that one could make the 'previous' current and 'next' image are visible and move the tray, 'unhiding' them as they reach those three positions.
In my own system, I skipped the 'tray' holding e images and only had them at -100% width, 100% width and the current one a 0.
I never had much luck with the typical long-tray carousel with large scale background images... Especially with css3 acceleration.

Resizing div with js from flash makes flash appear to freeze in chrome?

I have flash resizing it's container div by using external interface to call the javascript:
function expandbottomNav() {
document.getElementById('bottomNav').style.height = '400px';
}
function shrinkbottomNav() {
document.getElementById('bottomNav').style.height = '31px';
}
Now this appears to work fine in every browser except chrome. For some reason after the div is shrunk back down to size, the flash player looks like it's frozen. It's actually not frozen because if you resize the window the flash player starts playing again and you can see it had made progress since it appeared frozen. This only happens in chrome. Does anyone have any idea why something like this might happen?
The site so you can check it out yourself(yes I know it's a broken mess in IE, but I'm kind of ignoring that for now):
removed<
I'm at a loss as to why this is happening. I've tried different window modes but that doesn't help. The problem is when it resizes the div back down because if I comment that line out the flash never appears to freeze. But I need to be able to resize the div...
welcome ;)
it isn't frozen, the string is moving
at normal speed but is rendered only
when i move mouse cursor over it. did
you try setting object height to
certain amount of pixels each time the
div is resized? and did you try
scale='exactfit'?
I'm not sure of this but I remember that the "freeze" issue in Flash - in some browsers - was related to the return statement of the external JS functions.
Try to add something like return true; in your JS functions.
Ciao!

Difference in performance between img tag elements vs divs with background images?

Are there any differences in performance or load/caching behavior when displaying images in img tags vs divs with image backgrounds?
My example:
I have a site with many overlapping images, some of which I will need to load dynamically with javascript. One issue is that I need to anchor the images to the right of the element, so that I can do a nice wipe-to-right effect. Because of this I was using a div with background image positioned right. Couldn't figure out how to do this with img but since divs are working for me I didn't know if this would matter...
AFAIK, browsers cache images the same whether they're in a DIV or an IMG. In any case, I think this one of those cases where specific performance is defined as an implementation detail internal to each rendering engine (and possibly the browsers built around them). As such, it's both out of our control as designers/developers and subject to change from browser to browser and version to version. In other words, I wouldn't spend too much time worrying about it.
The main performance difference is using background images allows you to use CSS sprites. Having one image contain a large number of images from your page means the user only has to make one request instead of one for each image.
Another difference is with responsive layouts. If you have an element that is only shown at certain screen widths (ie, not on mobile phones), it will still load the image if it is specified in the html (using display:none for instance), but most all browsers now will NOT load the image if is a background-image specified in unused media query-CSS rules. A lot of early responsive layouts got criticized because they still used the same bandwidth as the full size sites.
It is also useful with such designs because you can easily specify different images for different screen sizes. "Retina" displays on tablets and even laptops now won't look their best without 2x res graphics. So... even if you don't do such things now, it is probably a good practice to get into, because you might find yourself needing it soon!
I think by using background-image attribute in the div, the page layout gets loaded first and image present in the divs loaded later after the dom is loaded. so by using background-image the html layout is loaded faster on the web browser.
The only difference I can conceive of it this:
You can't scale images as backgrounds, although you can for img tags. This would open a scenario where background images loaded faster becuase it forces you to have the correct native size as opposed to downloading the entire image and scaling it. However, the converse could be true: given that you didn't care about image quality so much, you could deliver smaller imgs to your page and scale them up.
I'd stick with whatever rendered cleaner (and more consistently -- IE/FF/Chrome/Safari/etc).
Technical differences yes, most notably you can set the width/height of an IMG tag and it will stretch the image, which can be useful in some situations.
The main thing you've got to keep in mind though is the context of the image within the HTML document. If the image is content, say an image in a gallery, I'd use a IMG tag. If it is just part of the interface I might use a div instead.

Categories