Home > Mobile >  Applying CSS transform on SVG group (e.g., D3's zoom transform) causes its text elements to fli
Applying CSS transform on SVG group (e.g., D3's zoom transform) causes its text elements to fli

Time:01-02

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 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 >
  <svg  width=300 height=300>
</div>

CodePudding user response:

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

  • Related