0

I have created a svg where I have the animation of a rectangle, and I would like to convert the duration of this animation (in this case 5 seconds) to a video. I am relying on this example:

https://plnkr.co/edit/SA4LfCHCbHcBxA48?open=lib%2Fscript.js&preview

but I don't know if it applies to my case, I have seen in some places that everything is done directly on a canvas, or the svg is somehow converted to an image or something like that. I tried to mimic the link logic, but I also get problems because that version of d3.js is older than mine.

how can do it?

d3.select("#visualization").append('svg');
var vis = d3.select("svg").attr("width", 800).attr("height", 614).style("border", "1px solid red");

var rectangle = vis.append("rect").attr("width", 100).attr("height", 70).attr("x", 0).attr("y", 50);

rectangle
  .transition()
  .duration(5000)
  .ease(d3.easeLinear)
  .attr("x", 250)
  .attr("width", 100)
  .attr("height", 100)
  .attr("opacity", 0.5)
  .attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="visualization"></div>
yavg
  • 2,761
  • 7
  • 45
  • 115
  • Well D3 renders an SVG. The SVG is then converted into a Blob and decoded as an Image. This image represents a single frame. This frame is then painted on a canvas. This is repeated for every frame in the animation. All the while a `MediaRecorder` instance will record what is happening on the canvas in the form of a stream. Whenever all the frames have been painted it will take the entire recording and convert it to an `video/webm` format. That's the gist of it. Quite complex, but you'll need to break it into small steps. – Emiel Zuurbier Oct 01 '20 at 14:02
  • d3 can be used with a canvas too, use your favorite web search engine, there are plenty of tutorials showing how to do it. But if really what you are doing is just moving a rectangle, you can certainly learn how to do it raw with a canvas directly in less than a few hours. Ps: don't go the convert to still image + decode + paint as raster + record way, the browser won't be able to cope. – Kaiido Oct 01 '20 at 14:04
  • The difference in your animation and the example you've given is that you're using a transition, while the example is changing the rotation at every step before converting it into an image. While this is not necessarily a deal breaker, it does require a different approach to capturing each frame. – Emiel Zuurbier Oct 01 '20 at 14:05
  • @Kaiido thanks for your answer, this is just an example, in my real project I have many more elements and animations. what it costs me to do and that I would like you to please help me please is how to do to generate those frames or whatever is necessary to make the video – yavg Oct 01 '20 at 14:06
  • As I said, the best is to draw directly using the canvas methods. You can still use d3 if you feel comfortable with it: here is one example among the many I talked about: http://bl.ocks.org/JMStewart/e6efab7dc6ca09702adb From there, all you have to do is call new MediaRecorder( canvas.captureStream() ). But the solution in your plunker will just blow the memory of any low end device (they are not even revoking the blobURIs they made) and is really just an ugly hack you shouldn't use. – Kaiido Oct 01 '20 at 14:07
  • @Kaiido thanks for your answer, I did not know that the link from which I was based had these memory problems. like i told you i have a real project with a lot of elements in my svg, i also have several transitions, so that's why i asked this question, i need some way to convert something like what i have in my code to video. I don't know if there is a trick or something to do this – yavg Oct 01 '20 at 14:23
  • @Kaiido So you recommend that I do all my logic directly on a canvas? I am following tutorials, but I want to know if what I have in this case (the transition of the rectangle) I can also do it on canvas. Is it possible to also enter images, texts and do what you normally would in svg? at this point i don't know when to use svg or canvas .. – yavg Oct 01 '20 at 16:26
  • Yes almost all you can do with svg can also be done on canvas directly, so yes if you want to record it as a video you'd be better drawing directly on a canvas. – Kaiido Oct 02 '20 at 00:09
  • @Kaiido wow ... coming from you that you are an expert it demotivates me a bit everything I have done using SVG directly. According to what I have researched, I cannot make transitions as easy as I did by manipulating svg elements, for example `ctx_rectangle.transition().attr ("x", 20)` will not work, is it correct? For example, this question that I have asked changes a lot to ask it on canvas, I would like to know how it would be done. – yavg Oct 02 '20 at 00:34
  • See the last lines of https://gist.github.com/armollica/99f18720eb9762351febd64236bb1b9e#file-index-html for an example of how to convert SVG to an image, then draw it on a canvas. But I agree with @Kaiido, it would be simpler to directly generate canvas. And you're right, [d3-transition](https://github.com/d3/d3-transition) is limited to modifying DOM element attributes (in HTML or SVG). To animate canvas, you have to loop and redraw (see https://observablehq.com/@mbostock/animation-loops for example) – Sylvain Lesage Oct 06 '20 at 13:00
  • @Kaiido Do you think that if I make a video of more or less 45 seconds using a canvas, the performance from a cell phone to generate a video will be good or will this slow down the browser? – yavg Oct 08 '20 at 13:26
  • The problem is not really that it will slow down the browser, but that converting from the DOM to an image is asynchronous, and you have no control on when the browser will do it, so it is entirely possible that it waits a bit before loading the image, which may result in multiple frames displayed in nearly the same time on the canvas and not at regular interval as needed by the MediaRecorder. You could use a [frame-by-frame recorder](/q/58907270), but this would also be incompatible with d3's transition as it would require being able to pause the animation every frame. – Kaiido Oct 09 '20 at 02:11

0 Answers0