Jump to content
GreenSock

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

problems with perspective IE (and tweening in Firefox)

Recommended Posts

Hi Guys, 

 

I'm having a few issues with a little page turner I'm trying to build. I started with Rodrigo's pen (Thank you :) ) and modified it to resemble a simple hard book (

See the Pen vjGxH by rhernando (@rhernando) on CodePen

) where you click the pages and they turn. It currently works quite well in Chrome, Opera and Safari, but has issues in IE and Firefox. 

 

Firefox nearly gets it, but doesn't animate the page shading on the before element quite correctly (using CSSRulePlugin). It correctly shades the first page as it's rising, but fails to animate the second page as it's dropping (that might make more sense if you view the demo in Chrome first, then in Firefox)

 

IE 11/10 ignore the perspective on the .Wrapper element. I've seen that you can keep the perspective in IE by repeating the transforms on the child elements, but this hurts my head when I try to do this with GSAP by setting values using TweenMax/TweenLite.

 

Does anyone have any ideas? I've not tried Edge yet... will give that a go later.

 

 

See the Pen ojpaeN by padders1980 (@padders1980) on CodePen

Link to comment
Share on other sites

Hello padders,

 

Take note that IE does not support transform-style:preserve-3d.  IE only supports transform-style: flat.

 

In order to get 3D transforms to work in IE you have to apply transformPerspective on each element. Even though you are setting it globally via CSSPlugin.defaultTransformPerspective = 5000;. That would set transform-perspective on each element. I would try setting it individually on each element that needs perspective instead.

 

Other browsers like Chrome and Firefox might not render right with global default perspective and or transformPerspective since that applies it to all elements. Which can cause some buggy behavior. Like i said above only apply perspective / transformPerspective on the elements that need it.

 

You should notice now that Firefox works now and IE (tested on PC Windows 7 64-bit):

 

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

  • I basically commented out this on line 1: //CSSPlugin.defaultTransformPerspective = 5000;
  • And applied transformPerspective: 5000 to only the .cardBack and .cardFront set() methods

Just a side note.. when declaring vendor prefixes. It is best to always place the standard CSS property last, so that is what will be the fall-back on in the browser.

 

So this:

.cardFront,
.cardBack {
  pointer-events: all;
  position: absolute;
  left: 100%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -ms-backface-visibility: hidden;
  width: 36vw;
  height: 24vw;
  overflow: hidden;
  background: hsla(0, 0%, 100%, 1);
}

would become this:

.cardFront,
.cardBack {
  pointer-events: all;
  position: absolute;
  left: 100%;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -ms-backface-visibility: hidden;
  backface-visibility: hidden; /* always put the standard CSS property last */
  width: 36vw;
  height: 24vw;
  overflow: hidden;
  background: hsla(0, 0%, 100%, 1);
}

Or you can just use GSAP to add the CSS properties that need vendor prefixes and leave the cross-browser heavy lifting for GSAP set() method.

 

Also i notice your doing a mix of CSS and GSAP for .book for  transform: translate(-50%, -50%); I would at that to your GSAP set() method as well so GSAP can record it, and keep track of it.

 

Here is an example of a CSS 3D cube i made that achieves this by adding transformPerspective only on each face, to workaround IE not supporting transform-style: preserve-3d

 

Some other examples of doing 3D in IE .. CSS only 3D cube preserve-3d workaround

 

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

 

And a 3D cube using GSAP:

 

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

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

 

I hope this helps! :)

  • Like 3
Link to comment
Share on other sites

Hi Jonathon, 

 

Thanks for that :) Good tip on the vendor prefixes. I'll make sure to do that from now on.

 

Unfortunately I still get the same problems with your pen as I did with mine (win 7 x64). IE ignores the rotationX set on the .Wrapper element. The 3d on the pages works OK.

 

Firefox still ignores the second page shading when a page flips. It shades the first page to move, but when the reverse page appears it isn't shaded.

 

I did try to use GSAP to set the transform on .book but I couldn't for the life of me get it to work! (even though I have in the past). I tried the following but the xPercent and yPercent just seem to be ignored.

TweenLite.set(".book", {
  transformStyle: "preserve-3d",
  top: '50%',
  left: '50%',
  xPercent:-50, 
  yPercent:-50
});

I also tried the following but it only applied the change in the x axis, not in the y!

TweenLite.set(".book", {
  transformStyle: "preserve-3d",
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)'
});

That was the point I set in the the css... (with a little whimper). I did wonder if it was something to do with me using viewing widths instead of set widths and heights?

 

Loving your cube demos. Very handy, I'll have a go and see if I can change my method to match. 

Link to comment
Share on other sites

Weird .. Im seeing it work, only when i click the bottom corner of the page on Firefox 41.0.2 .. on PC Windows 7 64-bit .. i am viewing the codepen so the HTML, CSS, and JS panels are on the left side, with the preview panel on the right. I think its not getting stuck. but more of an event binding issue.

 

I remember Carl saying something about the CSSRulePlugin .. having to make sure so your stylesheets are fully loaded, or something with parsing the CSS stylesheets. Maybe Carl or Jack can give greater clarification on that.

 

You can also try adding a window load event so you wait to run your code until the stylesheet is loaded. Since you are already using jQuery you can use a jQuery ready event and window load event :

// waits until the DOM is ready
$(document).ready(function(){

    // waits until all links, images, stylesheets, and other assets are loaded
    $(window).on("load",function(){

         // Place your code here

    });

});

I updated my previous codepen with a ready and window load event:

 

See the Pen JYpRGr?editors=001 by jonathan (@jonathan) on CodePen

 

Also same link but uses codepen Full mode, no editor:

 

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

 

And codepen debug mode , no iframe and no editor:

 

http://codepen.io/jonathan/debug/JYpRGr

 

You just change the /pen/ in the link to /full/ or /debug/

 

I wish i had a video recording software like Carl to show you the behavior it does on my screen. Very weird. I even tested in incognito mode (private browsing tab) to makes sure no extensions or addon affect codepen

 

i do notice with IE that sometimes you have to wrap your element with another div and rotate that separately on a different axis for 3D elements. I havent checked to see if new IE Edge support transform-style: preserve-3d yet. But IE always makes everything more difficult :blink:

 

Regarding translate(-50 -50) instead of using the transform as a property.. you could use the GSAP equivalent

TweenLite.set(".book", {
  transformStyle: "preserve-3d",
  top: '50%', /* i would set the 'top' in your CSS style sheet */
  left: '50%', /* i would set the 'left' in your CSS style sheet */
  //transform: 'translate(-50%, -50%)'
  x: "-50%",
  y: "-50%"
});

I usually set the initial position with left and top and then animate the object with x and y or xPercent and yPercent

 

So you separate the initial position using top, right, bottom or left in your stylesheet.. from what you want GSAP to animate.

 

Another side note is i would use a separate element besides an H1 tag for your title of the book. You are using multiple <h1> tags. There should only be one H1 tag on the page. This way your SEO will be better since search engines will ding your ranking, because Google, Yahoo, and Bing expects only one <h1> tag per page. I would use a <h2> instead or some other heading tag. You don't have to change the H1 element but its good for future reference so you don't lose any search engine rankings when your webpage goes live.  B)

  • Like 1
Link to comment
Share on other sites

Interesting, I'm not seeing any change with your updated version. I've attached some gifs of what I see (using ScreenToGif, not the best method but it does make nice small files!)

 

Firefox is at 41.0.2, IE is at 11.0.24 (11.0.9600.18059).

 

IE works perfectly other than the perspective.

 

Firefox has some weird shading issues. It applies the shading to the first page correctly, but not the second (I think it may be firing early and is done by the time the page appears?). So if you click the front of a page, it shades it correctly but the back isn't shaded when it appears. If you click the back, it shades that correctly, but not the front. That to me implies it's a timing issue? I've tried spreading them out a bit so there's no chance of overlap, and changing the way the timings are coded (using tags and +=) but that's not helped.

 

It's also shading both correctly on hover, but if you then click the page, it reverts that, and goes back to 0 opacity, then does the shading for the page turn. All the other browsers go from the hover to the fully shaded without reverting (which is what I thought the .to method would do). You might be able to see that in my gif... but it's a bit quick!

 

I have been playing with the debug mode too, as Firefox gets a bit picky with its sandboxing (that seems to stop some scripts from working in codepen)

 

I still have no luck with setting the .body alignment as you suggest. I've had it work like that in other codepens and projects... but for some reason it is having none of it this time. I can't seem to find what's blocking it, but I must have something out of line somewhere.

 

Another good tip on the h1 tags :) I'll bear that in mind.

 

Thanks for the help by the way, I'm constantly impressed by you guys on these forums!

post-37107-0-50957100-1445594657_thumb.gif

post-37107-0-70175100-1445594741_thumb.gif

Link to comment
Share on other sites

If I set the time period of the shading to be 0.65, and start it 0.75 after the page turn, then I can see it appears shaded, then abrubtly cuts out. It's like the .to event is firing instantly (like a .set).

 

Think I might leave it for now and move onto something else for a bit. Come back to it next week with a fresh head! Thanks for the help :)

Link to comment
Share on other sites

I'm thinking the shading bit in Firefox is being caused by the backface-visibility:hidden on certain flips back and front

 

You could try applying backface-visibility in your tweens for the front and back. So what i mean is remove backface-visibility:hidden from your css stylesheet. And then only apply backface-visibility:hidden (backfaceVisibility) or backface-visibility:visible on the card face that is either going forward or back on your clicks.

 

I did notice that in your CSS rules for :before you have all top, right, bottom, and left all set at 0. Its best to only use 2 of the position properties. Either use top or bottom and either left or right. So your intent is expressed which position you want. If you express all 4 then which ever one shows up last is used.

 

Also im wondering why you are using the CSSRulePlugin, if your just animating the background-color. If it was me i would just animate the background-color without the CSSRulePlugin. Making it simple as possible on what your animating, and then if you need the CSSRulePlugin then use it. But in your case i only see the background-color being the difference.

 

You could also look into using maybe a fromTo() tween if you want to control the start and end points with greater control

 

fromTo() : http://greensock.com/docs/#/HTML5/GSAP/TimelineMax/fromTo/

 

:)

  • Like 1
Link to comment
Share on other sites

Hi Jonathon, 

 

I'm using a :before element as I want to use background images and not just text on the pages. Shading the element means everything on the page is shaded nicely. The only other way I could think of was animating multiple background images, one being the image and one being a linear gradient. I think to do that I'd need to store the background images in the js and then animate the linear gradient, sticking them together to form one element. That seemed to be a bit more of a faff than animating a :before element! I might try it though. I didn't have the images in my demo as I haven't made them yet.

 

I'll have a play with the backface visibility, sounds like a good idea. I don't think it explains what Firefox is doing with the .to on page turn, when it's already hovered though (as in, the hover sets the opacity to 0.05, then on page turn it should smoothly animate to 0.2. However in Firefox, on page click it goes straight back to 0 opacity, then animates to 0.2. None of the other browsers do this. It looks like either a Firefox bug, or some strange GSAP behaviour where in firefox it does a fromTo instead of a To for some reason)

 

Setting all of the positional controls (top, bottom, left and right) to 0 means that the element will fill all the available space of it's parent. It's useful when the parents size isn't fixed, I could have gone with width and height at 100% but this way seems to be fairly standard for before and after elements. If you don't apply them all then the before element doesn't show.

Link to comment
Share on other sites

Usually with pseudo elements are positioned absolutely. I always set the width and height to 100%, so you make sure the behavior of your positioned elements are cross browser when wanting to fill the entire space of the parent. By declaring all 4 you will have issues with various modern browsers. Usually if you want to set all 4 position types you would use auto instead to override, since CSS will use the last position type that was declared when cascading. By its very nature an absolute element will fill its available space, unless that elements default display property is set to inline, or width and height is not defined. Otherwise you just set either top or bottom and either left or right.. and use display: block;

display: block; allows the element to fill it entire parents width and height. So there is no need to declare all 4 position types, for the reasons I discussed above. I would suggest to look at the spec below, some good reading :D

 

Below taken from compiled spec MDN:

 

https://developer.mozilla.org/en-US/docs/Web/CSS/position

  • Most of the time, absolutely positioned elements have auto values of height and width computed to fit the contents of the element. However, non-replaced absolutely positioned elements can be made to fill the available space by specifying (as other than auto) both top and bottom and leaving height unspecified (that is, auto). Likewise for left, right, and width.

Except for the case just described of absolutely positioned elements filling the available space:

  • If both top and bottom are specified (technically, not auto), top wins.
  • If both left and right are specified, left wins when direction is ltr (English, horizontal Japanese, etc.) and right wins when direction is rtl (Persian, Arabic, Hebrew, etc.).

Resources

W3C position spec: http://www.w3.org/TR/CSS2/visuren.html#propdef-position

W3C top, bottom, right, left: http://www.w3.org/TR/CSS2/visuren.html#position-props

 

:)

  • Like 2
Link to comment
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.
×