with this code I managed to make a video. I am not a very expert on the subject, but I would think that my problem occurs because I do not know how many frames I should use. for example I want my video to last 15 seconds (I don't know how to set it, I don't know how many frames I should indicate)
var queue = d3.queue(1);
d3.range(240).forEach(function (frame) {
queue.defer(drawFrame, frame / 240);
});
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();
}
}
});
how can I improve my code to get a smooth video?
const progressbar = document.getElementById('progressbar');
d3.select("#visualization").append('svg');
const vis = d3.select("svg").attr("width", 800).attr("height", 150).attr("xmlns", "http://www.w3.org/2000/svg").style("border", "1px solid red").style("fill", "white").style("background", "white");
const rectangle = vis.append("rect")
const circle = vis.append("circle");
let second = 0;
let interval;
const rectValues = {
"delay": 0000,
"duration": 5000,
"begin": {
"x": 0,
"y": 0,
"height": 70,
"width": 100,
"opacity": 1,
"fill": "red"
},
"destiny": {
"x": 250,
"y": 1,
"height": 100,
"width": 120,
"opacity": 0.8,
"fill": "green"
}
};
const circleValues = {
"delay": 4000,
"duration": 3000,
"begin": {
"cx": 250,
"r": 20,
"fill": "blue"
},
"destiny": {
"cx": 0,
"fill": "orange"
}
}
function startAnimation() {
//rectangle properties
startShapeAnimation(rectangle, rectValues);
//circle properties
startShapeAnimation(circle, circleValues);
}
function startShapeAnimation(shape, shapeValues) {
shape.attrs(shapeValues.begin)
.transition()
.duration(0)
.attrs(shapeValues.begin)
.transition()
.delay(shapeValues.delay)
.duration(shapeValues.duration)
.ease(d3.easeLinear)
.attrs(shapeValues.destiny);
}
startAnimation(0);
/***** CREATION OF VIDEO *******/
var canvas = document.createElement("canvas"),
width = 800,
height = 150,
context = canvas.getContext("2d");
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 queue = d3.queue(1);
d3.range(240).forEach(function(frame) {
queue.defer(drawFrame, frame / 240);
});
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) {
var img = new Image(),
serialized = new XMLSerializer().serializeToString(vis.node()),
url = URL.createObjectURL(new Blob([serialized], {
type: "image/svg+xml"
}));
img.onload = function() {
cb(null, img);
};
img.src = url;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<div id="visualization"></div>
<div id="contenedor_canvas"></div>