2

I notice that applying CSS transform on SVG groups would cause their children text elements to flicker in Safari. The transformation of other elements looks smooth in Safari. The transformation of all children looks smooth in Firefox or Chrome.

See below videos for example. The code is attached at the end of this post and also at https://codepen.io/xiaohk/pen/yLqOZXx.

Safari

enter image description here

Firefox

enter image description here

Chrome

enter image description here

Attempted Workarounds

I found several related questions:

However, all the solutions do not work for my problem. For example, I tried to set -webkit-transform-style:preserve-3d;, -webkit-transform: translateZ(0);, and -webkit-filter: opacity(1);.

Any suggestions are appreciated, thank you!

const svg = d3.select('.svg-element');
const group = svg.append('g')
  .attr('class', 'container-group');

group.append('circle')
  .attr('cx', 120)
  .attr('cy', 100)
  .attr('r', 20)
  .style('fill', 'pink')

const ys = [80, 100, 120, 140, 160];
const text = group.selectAll('text.my-text')
  .data(ys)
  .join('text')
  .attr('class', 'my-text')
  .attr('x', (_, i) => 250 + i * 10)
  .attr('y', d => d)
  .text('A quick and lazy fox.')

svg.call(
  d3.zoom()
    .extent([[0, 0], [500, 300]])
    .scaleExtent([1, 8])
    .on("zoom", zoomed)
);

function zoomed({transform}) {
    group.attr("transform", transform.toString());
}
.container {
  width: 100%;
  display: flex;
  justify-content: center;
  padding: 20px 0;
  -webkit-transform-style:preserve-3d;
  -webkit-filter: opacity(1);
}

.svg-element {
  width: 500px;
  height: 300px;
  border: 1px solid black;
}

g.container-group {
  -webkit-backface-visibility: hidden;
}

text.my-text {
  -webkit-transform-style:preserve-3d;
  -webkit-transform: translateZ(0);
  pointer-events: none;
  dominant-baseline: middle;
  text-anchor: middle;
}
<script src="https://d3js.org/d3.v7.min.js"  charset="utf-8"></script>

<div class="container">
  <svg class="svg-element" width=300 height=300>
</div>
Jay Wang
  • 2,650
  • 4
  • 25
  • 51
  • Have you tried [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)? It can prevent some rendering side effects and performance issues. Just an idea. – Pinke Helga Dec 31 '22 at 01:59
  • Thanks @PinkeHelga! I just tried it, and it didn't help :( – Jay Wang Dec 31 '22 at 02:02
  • Thank you @RobertLongson! `geometricPrecision` fixed my flickering issue! Can you add an answer? I will accept it. Happy new year! – Jay Wang Jan 01 '23 at 02:19

1 Answers1

3

Add text-rendering: geometricPrecision; that will stop Safari from adjusting the font kerning to best display the text at each scale.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242