Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Hysteresis

Scaling an element becomes pixelated

Recommended Posts

I am trying to have an element scale on mouseover but the div and the text inside is pixelated. I can't figure out why...

 

See the Pen BnlFi by dchadney (@dchadney) on CodePen

 

 

Link to post
Share on other sites

Hi Dan,

 

I looked around google regarding this issue but it seems that the usual -webkit-font-smoothing:antialiased won't cut it in this case.

 

I wrote about using SVG tags inside your <span> elements but I found what seems to be a better solution. Force the font to be an svg font. Simply create a font family and just set the only font as the SVG font, like this:

@font-face {
    font-family: 'MyWebFont';
        src: url('webfont.eot'); /* IE9 Compat Modes */
        src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
	     url('webfont.woff') format('woff'), /* Modern Browsers */
	     url('webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
	     url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
}

/* the fix ! simply ADD this block BELOW the above block */
@media screen and (-webkit-min-device-pixel-ratio:0) {
    @font-face {
        font-family: 'MyWebFont';
            src: url('webfont.svg#svgFontName') format('svg');
    }
}

Give that a try and let us know how it goes.

 

Here's the article if you want a complete read about it:

 

http://www.dev-metal.com/fix-ugly-font-rendering-google-chrome/

 

http://www.adtrak.co.uk/blog/font-face-chrome-rendering/

  • Like 1
Link to post
Share on other sites

Hello DanChadney, Welcome to the GreenSock Forums!

Sounds like a browser bug. Are you seeing this in Firefox or Google Chrome.. or both?

 

To add to Rodrigos great solution! I noticed you have the .hex in your css set  to scale3d(3,3,3) .. i have seen when you start your initial css using scale or scale3d to a higher value than one (1) which is the elements scale factor at 100%. Plus I noticed your font text in Chrome is very blurry, even with  -webkit-font-smoothing:subpixel-antialiased.

 

Have you also tried to maybe have your initial scale in the CSS be scale3d(1,1,1) and then use GSAP to set() the initial scale to 3

 

Or you can set the initial scale value to smaller value than 1, like say 0.7 in your CSS or use the GSAP set() method. And have all your hex elements scaled when hovered to 1.2 for the overshoot and then ease back in to scale 1 on hover.. ?

 

Check out this StackOverflow Topic: When scaling an element with css3 scale-it becomes pixelated until just after the animation completes.

 

Also i noticed in your tweens your using scaleX and scaleY to the same value. In that case you can just simply use scale property instead since both are the same.

 

:)

Link to post
Share on other sites

Thank you both very much for your replies. 

 

Unfortunately neither of these solutions are working for me using GSAP. The problem is in Chrome and it is happening to both the text and the containing div, so the SVG text solution will not work.

 

I can get it working using CSS transforms like this method: http://stackoverflow.com/questions/9986226/when-scaling-an-element-with-css3-scale-it-becomes-pixelated-until-just-after-t

 

But that only works if I remove all GSAP references to scale. Jonathan I tried both of the methods you mentioned, the first solution using the GSAP set() method is not working. The second won't work because I want to be able to scale past a value of 1. 

 

I got it working without GSAP here: 

See the Pen fojIb by dchadney (@dchadney) on CodePen

Link to post
Share on other sites

What OS and OS version are you seeing this on?

 

In Firefox the text gets pixelated right before the animation completes. I saw this in both your first and second code example.

 

In Chrome the first code example has the text very blurry in all states (initial, while animated, and when the animation completes) . The second code example in Chrome has the text slightly less blurry in the initial state and while animating.. but becomes clear once the animation completes.

 

Usually when i build a 3D cube and have text on the faces, I fix the blurry text by giving all the cubes faces a positive value using translateZ(), and then apply that same value but in the negative direction of translateZ() to the cube faces parent. And that fixes the pixelated text in a 3d cube. You could try using some sort of similar technique with translateX, translateY, translateZ. or translate3d().. Chrome is notorious for blurry fonts when using transforms.

 

To see something interesting.. add this temporarily to your code:

.hex.hover{
    -webkit-transform: translate3d(0,0,0) !important;
    transform: translate3d(0,0,0) !important;
}

You can see how clear and crisp the text gets when you zero out translate3d  .. the same would have with the non short hand translateX, translateY, and translateZ.  That's how crazy Chrome is with making fonts blurry in Chrome with transforms.

 

But... notice this codepen example i made. Notice the text is not blurry in Chrome or Firefox.

 

Scale element example with no blurry text:

 

See the Pen LKacj by jonathan (@jonathan) on CodePen

 

So since im not seeing my example as blurry as yours.. which makes me believe a combination of the transforms, pseudo elements (:before and :after), and z-index not present in my example, might be causing your blurry text in Chrome.

  • Like 1
Link to post
Share on other sites

Alright.. hours and next day later,  I figured out why your text is blurry in Chrome. This is definitely a webkit transform perspective bug. I forked your example and edited it. You will notice that there is no blurriness now.

 

Click my example SOLVED:

See the Pen pqwrs by jonathan (@jonathan) on CodePen

 

In your code you are setting a CSSPlugihn.defaultTransformPerspective for all elements set with GSAP.. which is for your .hex element. You are adding transform perspective of 600 to your .hex elements. Chrome displays your text blurry due to various webkit transform perspective bugs.

 

The workaround is to use perspective property and apply that to the .hex parent.. in this case .lab_item. The perspective property applies the perspective ( perspective(600) ) to its children whereas transform perspective ( transform: perspective(600) ) adds perspective to the element it is applied to.

 

So what i did was this:

// sets the default transform perspective property to .hex elements
// commented out due to webkit transform perspective bug
//CSSPlugin.defaultTransformPerspective = 600;
 
// use the perspective property on the .hex parent instead 
TweenMax.set(".lab_item", {css:{perspective:600}});

I was dealing with a similar issue but it was the reverse, and use transform perspective instead of perspective on the parent.

 

Various bugs in webkit for transform with perspective:

 

Issue 93682 in chromium: CSS 3D defect: -webkit-perspective property does not work.

Issue 51047: CSS3 perspective transform -webkit-transform does not work

Issue 54702 in chromium: -webkit-perspective doesn' work correct

 

Hopefully that helps! :)

 

** just a side note **

You should wrap a div around your .container div, and apply the CSS position: relative; .. so this way your absolute positioned div .container will be absolutely positioned relative to its parent (in this case the new div with position relative that will wrap the .container .div). Its just best practice to always set a parent of elements with position absolute to position: relative, so you can control the position. You could make .container .. position relative instead of absolute and will still except your top value.

  • Like 4
Link to post
Share on other sites

Nice work, jonathan! Gotta love browser bugs.  :x

  • Like 1
Link to post
Share on other sites

Wow, thank you for digging into this and figuring it out. That is very helpful. SOLVED!

Link to post
Share on other sites

Thanks Jack! and no worries Dan.. glad to help :D

Link to post
Share on other sites
Windows Registry editing fixed the font thickness issue for me completely, we can tune the font thickness/darkness by calibrating  FONTSMOOTHINGGAMMA  value to between 150 and 190 hexadecimal( 336 to 400 decimal )

 

    -     START  ->  RUN  ->  REGEDIT

    -     search for  FONTSMOOTHINGGAMMA   by  keying  " Ctrl F "  ( will automatically take us to  CurrentUser\ControlPanel\Desktop  path)

    -     double-click mouse on  FONTSMOOTHINGGAMMA    enter anything between 150 and 190 hexadecimal.(the Lower the value, the thicker the fonts.)

    -     close the REGEDIT tool

    -     LOGOFF and then LOGON

 

Now all the fonts are very thick & very dark in Chrome Browser.

 

But we must make sure that ClearType smoothing is enabled in Windows( controlPanel  ->  personalization  ->  appearance  ->   Effects   ->      ClearType smooth check [ ticked box ] )

 

                         OR  alternately in RegEdit ...

 

             FONTSMOOTHING=2

             FONTSMOOTHINGTYPE=2

             FONTSMOOTHINGORIENTATION=1  for LCD-screen,  0 for CRT-screen

Link to post
Share on other sites

Hi Raoyv and welcome to the GreenSock forums.

 

Thank you for submitting your advice.

I'm sure some folks will find it helpful if they need to adjust fonts on their own computers.

 

For anyone searching for answers regarding assets (fonts, images, svgs) getting pixelated during and even after an animation that uses transforms (scale, rotation, 3D) a great solution is to use force3D:"auto". Basically this tells browsers to use a transform:matrix3D during the animation (for hardware acceleration / smoother performance) which often causes the pixelation, but the "auto" part tells GSAP to remove the 3D matrix after the tween completes.

 

Here is a great demo from Jonathan: http://jsbin.com/gahujerexu/3/edit?html,css,js,output

 

Here is the discussion: http://greensock.com/forums/topic/10758-accelerated-scale-animations-do-not-repaint-after-tween/?hl=force3d

  • Like 1
Link to post
Share on other sites

Sorry to dig up some old posts but I'm getting this pixelated problem on scaled pictures but only on PC

So I tested it on Apple (firefox, chrome, safari) and PC (firefox, chrome, edge)

 

http://www.sharpness.be/demo/201602_keytrade/KTB_keypack201602_300x250_FR/

 

I made screenshots to illustrate the problem, the Apple version is a little crispier in reality but had to scale it down due to the retina screenshot,

but you can see the problem on the PC version, the borders of those png files are very ugly.

 

pixels.png

 

What I tried adding and didn't changed anything:

to the elements: z: 0.1, rotationZ:"0.01deg", force3D: true

to the parent container: css:{perspective:600}

to the elements: force3D: false

to the elements: transformPerspective:1000

Link to post
Share on other sites

This is not  a GSAP bug but the way the browser renders your images.

 

I have some questions:

  • Are those PNG files saved as png-24 or png-32, if not they must be to preserve transparency for edges?
  • What browser are you seeing this on?
  • What browser version are you seeing this on?
  • What OS on PC you seeing this on?
  • What OS version you seeing this on?
  • Also is the Apple display retina and the PC display not retina? (that can play a big part due to the pixel density)
  • I presume your seeing this in a webkit based browser like Google Chrome?

You have force:3d true on your element which in webki9t browsers will sometimes render images blurry or jaggy due to an anti-alias bug in webkit when elements are scaled. The browser will take a snapshot of your element and then place it on its own layer which can make images look horrible when transformed.

 

Also you should just leave or set force3D: "auto" which is default, so when the element stops animating, GSAP will remove the transform from the element.

 

Be careful to not scale elements passed a scale factor of 1. Otherwise you will be subject to various anti-alias transform bugs, mostly affecting webkit based browsers.

 

But again this is not a GSAP bug but just the way a browser renders certain elements with CSS transforms.

 

We need additional info to better offer solutions :)

Link to post
Share on other sites

That's what I thought :-/

  • My PNG are saved with https://tinypng.com/
    I think it's a mix of 8 and 24, it's very usefull for banners.
  • I only got the problem on PC with Windows 10, non retina display tested with those browsers:
  • firefox 37.0.2
    chrome 48.0.2564.109
    edge 25.10586.0.0
  • On the mac I've no problem but it's a retina mbp 15"
  • I removed the force3D: true or false
Link to post
Share on other sites

Usually if you don't want those jaggy edges as far as png.. then you must originally save your image png as PNG-32 which supports full alpha transparency. PNG 8 and PNG 24 only support partial transparency known as index transparency.

 

In Photoshop when saving for web:

  • if you save a png 24 with the transparency checkbox checked. Then Photoshop will save your image as a PNG-32
     
  • if you save a png 24 without the transparency checkbox checked. Then Photoshop will save your image as a PNG-24

Very important.

 

Only Adobe FireWorks would display Save for Web or save as PNG-24 or PNG-32

 

So i would go back to the source of your image and make sure it is saved as a PNG-24 or PNG-32.

  • png-8  is indexed transparency meaning its either on or off
     
  • png-24 is indexed transparency meaning its on or off
     
  • png-32 is alpha transparency and supports a range of opacity levels from 0.0 to 1.0

Hope this helps! :)

  • Like 3
Link to post
Share on other sites

I just put e.g. scale:1.12 instead scale:1.1 and works fine

  • Like 1
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×