• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

178
Views
Why following animation doesn't work as expected in different broswers

I have the following animation with svg, but they handled completely different on safari and chrome.

let time;
document.querySelector('text').addEventListener('animationstart', () => time = performance.now())
document.querySelector('text').addEventListener('animationend', () => console.log(performance.now() - time))
svg {
  width: 100vw;
  height: 50vh;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
    fill: black;
  }
}

text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 5s forwards;
  font-style: italic;
}
<svg>
 <text fill='none'  x="50%" y="50%"  text-anchor="middle" stroke="black" stroke-width="5.5" font-size="110">Example</text>
 </svg>

On safari, the animation will finish animating the stroke-dashoffset:0 almost close to the JS event print the finished ( 5s which I set), but on chrome, the animation will finish much faster (about 3 or 2 s). It will wait for several seconds for the animationend event to fire.

Also, the fill property on safari will not work at all.

What looks like in safari (with no fill black): enter image description here

My questions:

Why the two broswers handle animation differently and why the fill doesn't work as expected in Safari?

What am I missing?

about 3 years ago · Santiago Trujillo
1 answers
Answer question

0

For the fill issue, Safari will simply refuse to animate from none, while other browsers will use a discrete animation, as required by the specs. This will switch from none to black directly, at the middle of the animation time.
If you want a smooth transition then begin with a fill value of transparent.

setTimeout(() => {
  console.log("middle of anim");
}, 2500);
rect {
  animation: anim 5s linear forwards;
}
@keyframes anim {
  to {
    fill: black;
  }
}
<svg>
  <rect fill="none" width="50" height="50" />
  <rect fill="transparent" x="60" width="50" height="50" />
</svg>

For the dashoffset issue... that's a bit more complex. The value 1000 seems to correspond to Safari's computed path-length for this text, while other browsers have it closer to 500.

let time;
document.querySelector('text').addEventListener('animationstart', () => time = performance.now())
document.querySelector('text').addEventListener('animationend', () => console.log(performance.now() - time))
svg {
  width: 100vw;
  height: 50vh;
}

@keyframes draw {
  to {
    stroke-dashoffset: 0;
    fill: black;
  }
}

text {
  stroke-dasharray: 500; /* will draw half of the stroke in Safari */
  stroke-dashoffset: 500;
  animation: draw 5s forwards;
  font-style: italic;
}
<svg>
  <text fill="transparent"  x="50%" y="50%"  text-anchor="middle" stroke="black" stroke-width="5.5" font-size="110">Example</text>
</svg>

The proper solution for this case would be to compute the text's path length, but there is still no API that allows to do that. So the best in your case is to either convert your text to actual path data before-hand, either to use a web-font, analyze it through a library like opentype.js, and get the text info from there, though I didn't test this solution to see if Safari would match the library's results... so if you can, go with the <path> solution.

about 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error