Chrome reloading embedded SVG object when hiding and showing parent DIV container - javascript

I am using Adobe Edge Animate to do some CSS3 animations, and using a plugin that converts the SVG images to tags so that the SVG elements are accessible via Javascript. The problem is, when one of the parent DIV containers is hidden and later re-shown, the embedded SVG image is reloaded losing any changes that have been made to it, such as fill colors of shapes, etc.
This also causes some stuttering in the animation when a new image is loaded, as it takes a small amount of time to reload the image.
This problem is not present in Firefox or IE. Is there any way to tell chrome to not re-load embedded images when hidden and shown?
Here is a link to the page in question: Link
If you press the enter key, it triggers part of the animation. You can see after the rotation where it switches out the image and flashes. If you use the built in function via browser console called changeBladeColor() you can see how it resets any changed attributes. This function changes the fill colors of the shapes in the SVG.
Here is an example usage for testing:
changeBladeColor(1, '#ff0000');

It seems the only solution is to position the elements off the page. I had to re-do a lot of my animation, so keep this in mind when doing any projects where you need to display and hide objects (especially ones that may not appear to be doing so).

Related

In Chrome, SVG elements constructed too far off-screen do not render when brought into view

I am creating a web-site that drives content for a large 2D area off a CMS, so I have a system that runs on a timer, examines the part of the area that is currently on-screen, and loads content that is close enough to the view area that it might soon come into view.
This all seems to work quite nicely, apart from one small glitch.
Some of my content is SVG elements created procedurally via JS (the load mechanism feeds data from the CMS into JS functions, which create the using document.createElementNS and insert it into a div in the correct absolute position).
This content appears fine if is on-screen at the time it is loaded (this happens when the page is initially loaded).
And it also appears if it loaded while an animation is moving the visible area (animation is used to follow paths across the 2D space).
HOWEVER, if I am manually moving the visible area (which I have implemented via click+drag) then the SVG elements are added to the document tree, but when they come into view they do not render.
If I do something to "nudge" the renderer, such as hiding an unrelated element via DevTools, or resizing the window slightly, then they appear.
I am thinking this may be a bug in Chrome? e.g. where it has initially decided the elements need not be drawn and does not reprocess correctly when that needs reconsideration? Or maybe I am missing something, I am only semi-experienced in manipulating HTML documents via JS (but after a quick look I do not see the same behaviour in firefox...)
I am moving the visible area by changing the (left, top) of a parent element (I do not want to use scrolling for that as the size of the 2D space is not defined in advance...)
Otherwise, is there some way I could trick the browser into recalculating what should be drawn? I was wondering about having a small transparent element on screen that I show and hide on a timer, although a workaround that prevents the problem in the first place would be preferable...
Thanks for any advice!
Ian
p.s. I cannot instantly produce demo code for this as the code-base is moderately large, but I will spend time to make a simpler example if that proves necessary...

Loading base64 images through File API blocks DOM

I'm selecting some images in an input field, than I insert it into the DOM into img tags. Works fine, but I'm showing a simple SVG loader which doesn't animating. It shows up, but no rotation. In other cases the loader animates well. How should I prevent DOM blocking in this case?
Try to use some of CSS3 animation, for example, just find in google "css3 animation spinner", it is working without blocking.

How to enable clicking on layered svg images

My app uses up to 6 svg images layered to create an interactive image. I have found that I cannot mouseclick on any images below the first.
** Edit. Excess code and text removed.
You can make an element insensitive for mouse events by setting the pointer-events attribute to none (see Tinkerbin):
svg > *{opacity:.5}
In essence I cannot do what I want this way. Stacking embedded images results in only the top layer being clickable by the mouse.
An image map works, with some mucking about.
I created a clear image calling it clearOverlay and gave is a usemap value tying it to my image map.
My imagemap I created using a free online app http://www.image-maps.com which took my image allowed me to create my clickable zones and generated the html for me. After cleaning it up and swapping the href values for onclick functions I added the map to my code.
Next problem was getting it to overlay my existing images. I eventually used style="position:relative; top:-300px" forcing it to sit squarely on my image. I'm sure there must be a better way, but at this point that worked for me.
For anyone else doing this don't forget to either place the clearOverlay last in your image list or set the css z-index to higher than everything else to make sure it is sitting on top.
So I now have a stacked svg image, where I can manipulate each svg according to where the user clicks. Its only taken me 5 days! I'm kinda over this coding by yourself lark.
** My image map above will not scale to different sized screens. The next time I try this, I will experiment using a transparent svg with fill zones where I wish to click.

How to load multiple images quickly (without Css Sprites)

I am creating an avatar creator for iPad. Users can select different hair styles, hair colours, skin colours etc.
The page has two components: A selection area (where the selected options are shown as small thumbnails) and a preview area (where the selected options are shown larger).
Each option is saved as a SVG file. Using SVG has a number of advantages:
It remains sharp on Retina displays
The file size of each asset is tiny (as the images are vector based)
The files can be samll and still allow for transparency
The same images can be used for the preview/selection area (The browser just scales them via CSS).
Jquery is used to change the class ids on the oage which in turn effects the CSS code that is called (the CSS holds the SVG images as background images).
There is a large number of options, so to avoid overwhelming the user only relevant options are shown in the selection area. For example, if you tap red hair, then only the red hair styles are shown (all the other hair styles are hidden until the user selects the relevant colour).
Everything works fine, the only draw back is that when the user taps on an option there is a delay while the browser goes to fetch the images from the server.
How can I speed up the loading process, so there is no delay?
Here are some options I have considered:
CSS Sprites
Normally CSS sprite would fix this. However, because of the range of options, it isn't practical to create a CSS sprite by hand and none of the automated options support SVG sprite creation. If I switched to PNG, the file sizes would become very large.
Invisible Loading
I have created a hidden DIV that has all my images stored as background images (Using the CSS3 multiple background image property). This ensures all the images are loaded so they are available for instant display when the users taps on them. The only drawback is that this causes the page to take a long time initially load.
Are there any better options?
(Unfortunately, I can't provide a link to my work).
The way I did this in the end was to create a DIV that had all my images attached as a CSS3 multiple background. I then set the DIV to display:none. This loads all the images on page load.

mouseover element flickers

I have an image on a webpage and when the user hovers over it, another image appears. When then hovering over the appearing image, it flickers.
Anybody any idea why that is?
Tony
UPDATE: The first image does not dissapear when hovering, just another (smaller) image appears over the top in the left top corner. When now moving over that smaller image, then the flicker appears.
The image on the site is part of a gallery, so it's a php variable and gets loaded when a user selects from a list of images. So embedding one into the other is very hard.
Because the browser is fetching the new image. The best solution is to incorporate both images into one, and either purely use CSS to change the background-position on :hover, or ( for IE6 and non-anchor elements ) change the background position with JS.
In IE? IE is notorious for not caching images that are loaded dynamically (either with CSS :hover or due to Javascript events). You can use CSS sprites (basically, using one image file to display both images, and using positioning to show one or the other; tutorial, linked by Mike Robinson), or you can use image preloading:
var preloadImg = document.createElement('img');
preloadImg.src = 'path/to/image';
Edit: and other browsers will do the same on first load. IE just may continue to do it on every switch.
If I understand you right, you probably replace the src of your image every time the mouseover event is fired. So, even when your image is replaced, your event is fired and the image is replaced with itself, which may cause flickering.
I guess you're probably using IE. This is a bug with the way it implements caching in some versions. You fix it by either configuring your web server to send proper cache headers, or by using CSS sprites. I recommend the latter, as that means less HTTP requests, and the preloading works even without JS.

Categories