Answer the question
In order to leave comments, you need to log in
How to automate the process of capturing video (ScreenCapture) for SVG animation?
It is necessary to automate the process of capturing video (ScreenCapture) for the SVG element (animated via D3.js) in which the animation takes place. But how to automate - I have no idea. Just run a third-party recording program on the forehead and then cut both in time and cut out the desired area.
Sample thoughts: can translate SVG -> Canvas 60 times per second. It's weird, I guess... can svg->canvas even handle 60fps? Then send each frame to the script for assembling frames in WebM video. And all this at 60 frames per second. I think it might start to slow down. How else?
Environment: Linux.
Answer the question
In order to leave comments, you need to log in
Maybe this will fit?
Converting an SVG animation to a video with the MediaRecorder API and a hidden canvas.
https://gist.github.com/veltman/ff864215009174bc5d...
Here's an
SVG animation to video option :
use the Media Recorder API and a hidden elementcanvas
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<svg width="960" height="500"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
<script src="https://d3js.org/topojson.v2.min.js"></script>
<script>
var svg = d3.select("svg"),
canvas = document.createElement("canvas"),
width = canvas.width = +svg.attr("width"),
height = canvas.height = +svg.attr("height"),
context = canvas.getContext("2d");
var projection = d3.geoOrthographic()
.scale(195)
.translate([width / 2, height / 2])
.precision(0.1);
var path = d3.geoPath().projection(projection);
d3.json("/mbostock/raw/4090846/world-110m.json", function(err, world) {
var data = [],
stream = canvas.captureStream(),
recorder = new MediaRecorder(stream, { mimeType: "video/webm" });
recorder.ondataavailable = function(event) {
if (event.data && event.data.size) {
data.push(event.data);
}
};
recorder.onstop = () => {
var url = URL.createObjectURL(new Blob(data, { type: "video/webm" }));
d3.selectAll("canvas, svg").remove();
d3.select("body")
.append("video")
.attr("src", url)
.attr("controls", true)
.attr("autoplay", true);
};
var background = svg.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", "#fff");
svg.append("path")
.datum({ type: "Sphere" })
.attr("stroke", "#222")
.attr("fill", "none");
svg.append("path")
.datum(topojson.feature(world, world.objects.land))
.attr("fill", "#222")
.attr("stroke", "none");
svg.append("path")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) {
return a !== b;
}))
.attr("fill", "none")
.attr("stroke", "#fff");
var queue = d3.queue(1);
d3.range(120).forEach(function(frame){
queue.defer(drawFrame, frame / 120);
});
queue.awaitAll(function(err, frames){
recorder.start();
drawFrame();
function drawFrame() {
if (frames.length) {
context.drawImage(frames.shift(), 0, 0, width, height);
requestAnimationFrame(drawFrame);
} else {
recorder.stop();
}
}
});
function drawFrame(t, cb) {
projection.rotate([360 * t]);
svg.selectAll("path").attr("d", path);
var img = new Image(),
serialized = new XMLSerializer().serializeToString(svg.node()),
url = URL.createObjectURL(new Blob([serialized], {type: "image/svg+xml"}));
img.onload = function(){
cb(null, img);
};
img.src = url;
}
});
</script>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question