D3 Zoom with Lottie File

Is it possible to scale a lottie file with call `d3.zoom()?
I tried it with these examples on codepen but wasn’t successful.
Thanks a lot for your help!

I don’t think that Lottie is a library that folks here are likely to have a lot of experience with. Also, your “examples on codepen” link points to a page on the D3 in Depth site.

It does appear, though, that there is a Hello lottie-web notebook here on Observable - one that’s been forked many times. Inspecting that notebook, it appears that Lottie produces SVG, which is easily manipulated by D3. In particular, we can create an SVG with a g element, load a Lottie animation into that g element, then call d3.zoom on the containter SVG.

Here’s that strategy in action:

Thanks a lot for your help!

To me, D3 and Lottie seem to be a dream-team that combines the programming power of d3 and the design features of After Effects=>Lottie.

I did a proper Codepen with a linked Lottie file.

The only problem I have: I cannot figure out why the zoom center is not under the cursor when pinch zoomed…

In your definition of handleZoom, you’ve got:

function handleZoom(e) {
  d3.select('svg g')
    .attr('transform', e.transform);
}

If you change that to

function handleZoom(e) {
  d3.select('svg svg')
    .attr('transform', e.transform);
}

I think it will work as you expect.

The setup seems a little awkward. You’ve got an

<svg class="lottie"></svg>

in your HTML. You then call lottie.loadAnimation on that SVG, which produces another SVG nested inside your original. I guess that’s not how Lottie usually works but we’re essentially using it to our advantage here.

Great, thank you very much! The zoom problem is solved.

And I would like not to have the awkward SVG in the SVG issue, but I wasn’t able to get it right with putting the Lottie-SVG directly in a DIV. Every time I tried, the D3-zooming went crazy. But if someone sees a solution, I would very much appreciate.

I think that a better solution might be to set up your HTML structure as follows:

<div class="divclass">
  <svg class="lottie">
    <g id="zoom"></g>
  </svg>
</div>

You can then load the animation into that g element:

lottie.loadAnimation({
  container: document.querySelector("#zoom"),
  ...
})

The handleZoom function should then modify that g element:

function handleZoom(e) {
  d3.select('g#zoom')
    .attr('transform', e.transform);
}

You still have nested SVGs but that’s no problem, as svg is a legal SVG element.

I think this is preferable because you’re no longer modifying the SVG that was produced by Lottie. That SVG might, for example, have a transform attribute that you don’t want to overwrite. That was the case in the original example I wrote, which is why I put the g element in there then.

Super helpful again, thank you very much! It works perfectly.

I’m looking forward to making projects with D3 and Lottie.

Best regards from Switzerland