总结
通过canvas的captureStream属性返回的一个MediaStream对象,将生成的stream通过MediaRecorder对象生成录屏资源
const canvas_sun = require('./assets/canvas_sun.png')
const canvas_earth = require('./assets/canvas_earth.png')
const canvas_moon = require('./assets/canvas_moon.png')
function Draw () {
const canvas = useRef();
const recorder = useRef();
const sun = new Image();
const moon = new Image();
const earth = new Image();
const init = () => {
canvas.current = document.getElementById("canvas");
sun.src = canvas_sun;
moon.src =canvas_moon;
earth.src = canvas_earth;
window.requestAnimationFrame(draw);
}
const draw = () => {
const ctx = document.getElementById("canvas").getContext("2d");
ctx.globalCompositeOperation = "destination-over";
ctx.clearRect(0, 0, 300, 300); // 清除画布
ctx.fillStyle = "rgb(0 0 0 / 40%)";
ctx.strokeStyle = "rgb(0 153 255 / 40%)";
ctx.save();
ctx.translate(150, 150);
// 地球
const time = new Date();
ctx.rotate(
((2 * Math.PI) / 60) * time.getSeconds() +
((2 * Math.PI) / 60000) * time.getMilliseconds(),
);
ctx.translate(105, 0);
ctx.fillRect(0, -12, 40, 24); // 阴影
ctx.drawImage(earth, -12, -12);
// 月亮
ctx.save();
ctx.rotate(
((2 * Math.PI) / 6) * time.getSeconds() +
((2 * Math.PI) / 6000) * time.getMilliseconds(),
);
ctx.translate(0, 28.5);
ctx.drawImage(moon, -3.5, -3.5);
ctx.restore();
ctx.restore();
ctx.beginPath();
ctx.arc(150, 150, 105, 0, Math.PI * 2, false); // 地球轨道
ctx.stroke();
ctx.drawImage(sun, 0, 0, 300, 300);
window.requestAnimationFrame(draw);
}
const record = () => {
const stream = document.getElementById("canvas").captureStream();
recorder.current = new MediaRecorder(stream, { mimeType: 'video/webm' });
const data = [];
recorder.current.ondataavailable = function (event) {
console.log('event---record',event)
if (event.data && event.data.size) {
data.push(event.data);
}
};
recorder.current.onstop = () => {
const url = URL.createObjectURL(new Blob(data, { type: 'video/webm' }));
document.querySelector("#videoContainer").style.display = "block";
document.querySelector("video").src = url;
}
recorder.current.start();
setTimeout(() => {
recorder.current.stop();
} ,6000)
}
useEffect(() => {
init();
}, []);
useEffect(() => {
if (!canvas.current) {
return
}
setTimeout(() => {
record();
}, 100);
}, [canvas.current])
return (
<div>
<canvas id="canvas" width="300" height="300"></canvas>
<div id='videoContainer' style={{display:'none'}}>
<video width="300"
height="300"
controls="true"
autoplay="true"
id="video"
></video>
</div>
</div>
);
}