1

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.

nrkn
  • 1,752
  • 3
  • 15
  • 24
  • You could use CSS animations, which will scale the container as if it were a bitmap. – alex Feb 25 '13 at 02:28
  • You need to set overflow: hidden on the container, and then apply the animation to the container. – Epik Feb 25 '13 at 03:05
  • Epik - that won't help in this case, but thanks anyway. – nrkn Feb 25 '13 at 03:15
  • For what it's worth, in Firefox, the initial text is about 12pt, while in Chrome the intial text is about 2pt. – JakeParis Feb 25 '13 at 03:21
  • What about blurring the text while the animation is happening? – cimmanon Feb 25 '13 at 03:22
  • JakeParis - do you have a minimum font size set, possibly in user style sheets? I see it at about 2pt or so here in Firefox – nrkn Feb 25 '13 at 03:35
  • @nrkn, yes in fact I do. Jeez I must've set that ages ago and forgot all about it! – JakeParis Feb 25 '13 at 04:41
  • @alex actually css animations/transform does the same thing see http://jsfiddle.net/nRc7U/ – abbood Feb 25 '13 at 05:00
  • @abbood You're animating the `width` and `height`. Try `scale()`. – alex Feb 25 '13 at 05:20
  • @alex `scale()` causes a [blurring](http://www.the-art-of-web.com/css/css-animation/#.USr5MOv25r0) effect when the text is being zoomed (it's exactly how you said it, it scales text as if it were a bitmap.. and since bitmaps are not vector graphics.. pixelation/blurring/general quality degradation is expected). Although I admit that using scale is a much faster and easier solution than the one I [suggested](http://stackoverflow.com/a/15060711/766570). – abbood Feb 25 '13 at 05:42
  • @abbood Yeah it does, was just suggesting it as an alternative. – alex Feb 25 '13 at 05:51
  • @alex gee I wonder where nrkn disappeared? lol – abbood Feb 25 '13 at 05:52
  • @abbood - I was working on something else, have a deadline tonight so have only just had an opportunity to look back into this now. Would it still create a blurring effect if the preview was initially created at 100% font-size and then scaled down via scale, then back up again - rather than being initially at the small size and just scaled up? – nrkn Feb 25 '13 at 05:53
  • yes. Again the blurring is caused by *how* the animation rendering is happening.. in this case it seems that text is converted into a bitmap.. then it's scaled etc.. so it doesn't matter what the initial font-size is. – abbood Feb 25 '13 at 06:05
  • OK thanks - it might not matter so much if the bitmap is being downscaled from a larger size though, typically downscaling produces less offensive blurring than upscaling. I'll have a play. Thanks again! – nrkn Feb 25 '13 at 06:32
  • Also only webkit is blurry - it appears that Gecko/Trident/Presto handle it fine. – nrkn Feb 25 '13 at 06:51
  • interesting.. if you told me it was only IE that has this trouble I wouldn't be concerned.. but webkit is big time, and more browsers are [adopting](http://news.cnet.com/8301-1023_3-57569106-93/opera-embraces-webkit-in-browser-brain-transplant/) it as a rendering engine.. keep us posted with your attempt to downscale bitmap.. this discussion is definitely instructive – abbood Feb 25 '13 at 07:01

4 Answers4

1

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.

Community
  • 1
  • 1
abbood
  • 23,101
  • 16
  • 132
  • 246
  • It's an extremely clever solution, and thanks for spending so much time on it - but unfortunately it's not going to be suitable because as I mentioned in my question, although the fiddle is just using text, the previews will actually contain arbitrary HTML. – nrkn Feb 25 '13 at 05:52
  • clever enough to receive a vote up? ;) anyways, in your case.. i think you should prolly stick with `.scale()`.. it all depends on how much time you want to invest on this problem. – abbood Feb 25 '13 at 06:08
  • Yes :) Voted up. As per my comment above I might give scale a shot. – nrkn Feb 25 '13 at 06:33
0

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

Tammy Shipps
  • 865
  • 4
  • 13
  • Unhappily, it doesn't make a difference - the small changes still occur even with a monospace font. Thanks anyway. – nrkn Feb 25 '13 at 03:19
0

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.

JakeParis
  • 11,056
  • 3
  • 42
  • 65
0

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 (i.e. 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).

bhotel
  • 472
  • 5
  • 11