Jump to content
Search Community

Recommended Posts

Posted

I'm using Split Text but I get weird line breaks when animating. I believe it's due to not letting my custom font load first but I'm unsure how to solve this. I've gone through the forums but I haven't seen a clear answer. Here is the code I have...

 

// Hero animation
var heroTimeline = gsap.timeline({
paused:true,
onComplete: () => {splitLines.revert()}
});

const splitLines = new SplitText('.hero .block-animate', {type: "lines", linesClass: "line"});
$('.hero .block-animate .line').wrap('<div class="line-wrapper">');

heroTimeline.from(splitLines.lines, 1.25, {y: '150%', ease: "Power3.Out", stagger: 0.15}, 0.25);

window.onload = () => {
heroTimeline.play();
}

See the Pen BajBJEV by jeffdfarr (@jeffdfarr) on CodePen.

Posted

I can provide the live URL where I'm seeing this behavior but I don't know where to mark the message private.

ZachSaucier
Posted

Hey Jeff. You should be able to have SplitText wait until your fonts are loaded by using 

document.fonts.ready.then(function () {
  // Your code here
});

Keep in mind that the above won't work in IE due to browser support.

  • Like 4
Posted

That seemed to help on the drastic breaks but there are still some small line breaks issues. Here is my code below. Again, I can provide the live URL if hidden.
 

// Hero animation
document.fonts.ready.then(function () {
  
var heroTimeline = gsap.timeline({
onComplete: () => {splitLines.revert()}
});

const splitLines = new SplitText('.block-animate', {type: "lines", linesClass: "line"});
$('.block-animate .line').wrap('<div class="line-wrapper">');

heroTimeline.from(splitLines.lines, 1.25, {y: '150%', ease: "Power3.Out", stagger: 0.15}, 0.25);

});

 

ZachSaucier
Posted
19 minutes ago, jeffdfarr said:

I can provide the live URL if hidden.

Can you not re-create something similar in CodePen? It doesn't have to be the content that you're using on your actual site.

 

Side notes:

  • In GSAP 3, we recommend putting the duration inside of the vars parameter.
  • Your ease is invalid: you should use either use the condensed string form ("power3") or the old object form (Power3.easeOut).
  • You might want to use yPercent: 150 instead of y: '150%'.
Posted

Okay, I updated the width to what it's like on the live site. (

See the Pen BajBJEV by jeffdfarr (@jeffdfarr) on CodePen.

) You can now see the weird breaking. Also, I will fix those side note issues. Thank you!

Posted

That seems like a bandaid to fix the problem. It does similar behavior for other sections of my website as well. 

Posted

Yep, it literally can't take kerning into account. It's impossible, not a bug. That's why this note has always been in the SplitText docs :) 
 

Quote

 

Some browsers (like Safari) apply custom kerning by default between letters, so when characters are split apart and put into their own divs, the spacing is slightly different. A bug has been filed with the Safari team (it’s a browser issue, not SplitText) but you can typically eliminate the differences by setting these CSS properties:


font-kerning: none;
-webkit-text-rendering: optimizeSpeed;
text-rendering: optimizeSpeed;
-webkit-transform: translateZ(0);
transform: translateZ(0);

 

 

 

Sorry, I wish I had better news for you. I can't think of any way to accommodate custom kerning like that. If anyone else has ideas, I'm all ears. 

  • Like 3
Posted

Oh I didn't realize there was kerning on the font. That seemed to fix the problem. Thank you!

  • Like 1
  • 9 months later...
Posted

Just to add - as this tiny fractional jump was being stubborn after .revert

 

Some custom webfonts (the one I was using, of course) will force what looks like ligature adjustments (fi or ff for example) in Firefox and Safari (OSX Big Sur), regardless if these are set or unset with the CSS:

 

font-kerning: none;
-webkit-text-rendering: optimizeSpeed;
text-rendering: optimizeSpeed;
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-font-feature-settings:normal;
font-feature-settings:normal;

 

The only workaround I could find was to set css letter-spacing to a tiny increment like 0.01em.

 

Ta, Liam

  • Thanks 1
Posted

I am prepared to get a lot of bashing for that comment, but I jus can not resist:
There are times, when I really miss Flash.

*duck*

  • Like 1
  • Haha 1
Posted

Last addition to this.

 

On longer text passages... with some webfonts... with text over multiple lines... in safari (v/OS as above)... depending on line length and ragged edge paragraphs... sometimes words will find a home on the next line when .revert() has finished. Very ugly.

 

The only way I could get round this was target safari and add <br> via the CMS where I needed them in the passage and be super mindful via media queries  (I'm already detecting Safari as it is). Will also need to the run the splittext + revert again on resize.

 

This won't work well for dynamic passages — where I'd imagine youd need to do something more fancy with line count.

 

TLDR;  Safari + SplitText + (some?) Custom webfonts are not kindred spirits

 

 

Posted

@limbo thanks for sharing that. Yeah, as far as I can tell, that's purely due to the fact that Safari applies custom kerning only in certain scenarios, so if you split the text apart, it refuses to do that. If you have any specific suggestions for workarounds, I'm all ears. I'm curious: did you try setting tag: "span"

Posted

Hello Jack

 

I did try tag:"span", — but as I'm using lines it doesn't seem help or make any difference in that respect.

 

Thanks for the suggestion though.

  • 3 weeks later...
Posted

Still working on this and found a nice way to cope with the problems I was having with custom font... only  run revert on resize. Seems obvious now.

 

function debounce(func){ // to throttle
  var timer;
  return function(event){
    if(timer) clearTimeout(timer);
    timer = setTimeout(func,150,event); // 150ms seems like a good sweetspot
  };
}
window.addEventListener("resize",debounce(function(e){

  mySplitText.revert();

}));

Needs testing on device - works well on desktop inc. Safari OSX.

  • Like 2
  • 4 years later...
Posted
On 6/1/2020 at 9:08 PM, ZachSaucier said:

Hey Jeff. You should be able to have SplitText wait until your fonts are loaded by using 

document.fonts.ready.then(function () {
  // Your code here
});

Keep in mind that the above won't work in IE due to browser support.

This is so handy! Thanks. 

Posted

Hi @limbo,

 

With the complete re-write in version 3.13.0, SpliText also has the autoSplit config option and the onSplit callback:

https://gsap.com/docs/v3/Plugins/SplitText/#autoSplit*

https://gsap.com/docs/v3/Plugins/SplitText/#onSplit*

 

For simple one-off animations that is super simple and the onSplit callback will be executed after the custom fonts are loaded, so it might be useful to have a peek at it.

 

Happy Tweening!

  • Like 1
Posted

image.png.1e27f26a25743e8c093140c5e902baaf.pngdayuuum 😄

on topic: I've always wanted to use onSplit, but have been unsure how to have that work with splittext animations that are part of a larger timeline that can't really be defined in that callback?

  • Haha 1
Posted

Hi Nick!

 

In the case of using a Timeline that is created outside the onSplit callback, you have to add a label to position the text animation and shift the next Tween the amount of seconds the text animation lasts in order to properly create the sequence. The main issue here is the fact that the custom font could be loaded after the rest of the Timeline is created, so the the challenge is to kind of squeeze (for lack of a better word) or properly fit the SplitText animation in the Timeline without causing a problem for the rest of the sequence.

 

This is an extremely simple demo that show this approach:

See the Pen MYadwOP by GreenSock (@GreenSock) on CodePen.

 

Is worth mentioning that you can also use shiftChildren if you can't anticipate the duration of the SplitText animation:

https://gsap.com/docs/v3/GSAP/Timeline/shiftChildren()

 

Hopefully this helps

Happy Tweening!

  • Like 1
Posted

Actually, here's a fork that demonstrates a way that might be easier: 

 

See the Pen MYadarw?editors=0010 by GreenSock (@GreenSock) on CodePen.

 

The helper function that's key: 

/* 
This helper function can be used just like a regular SplitText except that it returns the animation
from the onSplit() so that you can insert it into a timeline (or do whatever you want with it). 
It also handles killing that animation when onSplit() is called again, and it'll swap the new 
animation into exactly where the old one was, making it seamless. For example: 

let tl = gsap.timeline();
tl.to(...)
  .add( SplitTextAnimation(target, {
          type: "words,chars",
          onSplit(self) {
            return gsap.from(self.chars, {y: 100, stagger: 0.1})
          }
      })
  )
  .to(...);
*/
function SplitTextAnimation(target, config) {
  let animation,
      onSplit = config.onSplit;
  config.onSplit = self => {
    let parent, startTime;
    if (animation) {
      parent = animation.parent;
      startTime = animation.startTime();
      animation.kill();
    }
    animation = onSplit && onSplit(self);
    parent && parent.add(animation, startTime || 0);
  }
  SplitText.create(target, config);
  return animation;
}

That way, you don't have to pre-calculate the duration/stagger and offset subsequent animations using the position parameter. Remember, the onSplit() will get called immediately, and then again when the fonts load. Don't forget to return the animation in the onSplit() because that's what allows it to get funneled back to the helper function which passes it along too. 

 

I hope that helps! 

Posted
7 minutes ago, GreenSock said:

Actually, here's a fork that demonstrates a way that might be easier: 

 

 

 

 

The helper function that's key: 

/* 
This helper function can be used just like a regular SplitText except that it returns the animation
from the onSplit() so that you can insert it into a timeline (or do whatever you want with it). 
It also handles killing that animation when onSplit() is called again, and it'll swap the new 
animation into exactly where the old one was, making it seamless. For example: 

let tl = gsap.timeline();
tl.to(...)
  .add( SplitTextAnimation(target, {
          type: "words,chars",
          onSplit(self) {
            return gsap.from(self.chars, {y: 100, stagger: 0.1})
          }
      })
  )
  .to(...);
*/
function SplitTextAnimation(target, config) {
  let animation,
      onSplit = config.onSplit;
  config.onSplit = self => {
    let parent, startTime;
    if (animation) {
      parent = animation.parent;
      startTime = animation.startTime();
      animation.kill();
    }
    animation = onSplit && onSplit(self);
    parent && parent.add(animation, startTime || 0);
  }
  SplitText.create(target, config);
  return animation;
}

That way, you don't have to pre-calculate the duration/stagger and offset subsequent animations using the position parameter. Remember, the onSplit() will get called immediately, and then again when the fonts load. Don't forget to return the animation in the onSplit() because that's what allows it to get funneled back to the helper function which passes it along too. 

 

I hope that helps! 

Amazing, thanks. Just always something I've wondered, and I've been ignoring console warnings about splittext so far because I haven't quite known how to deal with it 😊

  • Like 1

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.
×
×
  • Create New...