简体   繁体   中英

Avoid text wrapping while doing a jQuery animate on font-size

I have some content which is displayed at at a preview scale, by using em for everything and then scaling the root font size when I want to reduce/enlarge, so can you see the full content by clicking on the preview, at which point I use jQuery to animate the font-size up to 100%:

http://jsfiddle.net/5fCd5/3/

So basically:

CSS:

.example section {
  font-size: 30%;    
}

JS:

zoomed.animate({
  fontSize: '100%'
});

But see the fiddle to get a better idea.

The problem is, that although the container is scaling with the font size, the browser will wrap the text at slightly different points throughout the animation - I understand the logistics of why this happens (different proportions of characters when rendered at different sizes/hinting etc.), but it looks awful. It's much more noticeable in Chrome than it is in Firefox. Interestingly IE10 doesn't change where the lines wrap at all. This is on Windows - possibly the font rendering on OSX doesn't have this issue.

Can anyone think of some kind of fix or workaround?

One workaround that I considered initially was:

Create the preview at 100% font size, split the text on whitespace, add it to the container one word at a time, when the container increases in height store the position, then wrap each line in an element with whitespace no-wrap and give the container overflow: hidden.

However as I want to use arbitrary HTML (including images sized in ems) for the previews, this isn't really feasible.

the idea is that by enlarging regular text, you are giving away the decision of how to enlarge it to css/html. You want to devise a method where you have more control on the animating and zooming of your text.

An example of that would be converting your text into a bitmap then scaling it. That would be a poor choice for obvious reasons, such as the high cost of converting a font into a bitmap, as well as that a bitmap itself will look pixelated once it's scaled (ie there is quality loss). Additionally, even using css scale() causes some blurring when you zoom in and out (see comments under original question).

my suggestion:

  1. First of all convert your font into a canvas equivalent using cufon . Cufon uses a mixture of Canvas and VML to render the fonts.
  2. Using cufon/canvas is a good first step. However, if you look at an example of a cufonned text here you will notice that if you zoom in and out, you will see the same pixelation/quality loss symptom that's normally associated with bitmaps. Further research proves the point that canvas zooming will show pixelation (see this example http://jsfiddle.net/mBzVR/4/ ).
  3. To go around that, instead of simply scaling your canvas by multiplying with and height by a number for example.. you can render your canvas at a 25 Frames Per Second (FPS), slightly increasing/decreasing its size at every frame rendered at 1/25 second. I got this idea from Flot which is a jQuery library for rending canvas charts. If you look at their home page example.. you will see a chart being animated by panning left/right. If you save that page.. you will see something like this in flot.demo.js:

from flotcharts.org :

// Update the random dataset at 25FPS for a smoothly-animating chart
setInterval(function updateRandom() {
    series[0].data = getRandomData();
    plot.setData(series);
    plot.draw();
}, 40);

This way you can totally control your animation wrapping and ensure that no pixelation/zooming is happening.

I suggest using a monospaced font - that would eliminate the small spacing changes that you're seeing when the font size is changing on animation. Here is one that you can try on Google Web Fonts to see if, at least, you don't get the same issues.

http://www.fonts.com/search/web-fonts?searchtext=Helvetica+Monospaced&SearchType=WebFonts&src=GoogleWebFonts

Using css letter-spacing ing the div.padder like:

letter-spacing: 1px;

makes a bit of difference, thought I don't know if it's exactly the change you're hoping for.

Hm. On my Mac, Firefox has no issues whatsoever, but Chrome is worse than I think you've noticed–the text exceeds the bounds of the container after the resize.

I think we might need to back up one step and think the problem through one more time. So:

  • there are arbitrarily-sized (though identical) containers of text ("text containers")
  • these containers are contained in another arbitrarily-sized container ("outer container")
  • browsers wrap text according to how many words can fit into the width of the container (assuming overflow: auto; )
  • so, assuming that all of these things maintain their relative sizes during the resize , the symptom you describe should be impossible (absent browser bugs and whatnot...)

That process of reasoning led me to check your jsfiddle, and sure enough, it is not the case that the various parts in your example retain their relative sizes during the resize .

On my machine (a laptop, so the pixel sizes are small, but that doesn't affect the logic here), the individual text containers (the innermost .padder ) have an aspect ratio of 143px / 53px = 2.70 , while the outer container ( .examples ) has an aspect ratio of 526px / 253px = 2.08 .

This has the following consequences:

  • the proportion of line-length to container-width changes during resize
  • so, at least for some lines in some cases, the locations of the linebreaks must also change during resize

There is only one solution I can see to prevent the problem you're experiencing: force the outer container and text containers to have the same aspect ratio (ie since any solution that involves using actual HTML text and changes the aspect ratio during transformation will have the same issue).

This should also correct the problem that I'm seeing in Chrome where the text height exceeds the height of the container. This is happening because the number of lines changes, but the height of the scaled-up text container is predetermined by the outer container (which is completely unconnected to the height of the text in the text container).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM