原理
这篇乱了,请看最新的文章,点击链接 最新的文章
原理是比较简单的,如果层div里面没有svg,简单使用div 的html 画到canvas上,然后使用canvas的方法直接下载到本地或者由内存传输到后台,但是更好的传输是canvas的capturestream 直接取出h264,很多人总是使用toDataURL方法,传输时由于是base64编码,数据量会大很多,30%左右,可以使用toBlob方法,直接成为二进制png文件,使用方法如下:
canvas.toBlob(function(blob) {
var url = URL.createObjectURL(blob);
//downloadByBlob(blob,filename);
var newImg = document.createElement("img");
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
});
保存文件
上面这种方法是很正规的,也可以使用 await canvas.toBlob() 方式,这样是如协程方式去等待事件,不用回调。如果要下载
function downloadByBlob(blobObj,filename) {
const link = document.createElement('a');
link.style.display = 'none';
const downloadUrl = window.URL.createObjectURL(blobObj);
link.href = downloadUrl;
link.download = filename;
//link.download = `test.png`;
document.body.appendChild(link);
link.click();
link.remove();
}
这样就可以直接下载到本地。如果有svg在里面,可以使用canvg.js,读者可以自己试验
html
.water {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear 1;
}
.no-water {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
}
.first-run {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear 1;
}
.runing {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: run 10s linear infinite;
}
.runwater {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: run 10s linear infinite;
}
@keyframes dash {
to {
stroke-dashoffset: 0;
}
}
@keyframes run {
from {
stroke-dasharray: 10, 5;
}
to {
stroke-dasharray: 40, 5;
}
}
保存
this is div 测试1
this is div 测试2
这是干啥
点击动画
var keybtn = document.querySelector('#key');
var water1 = document.querySelector('#water');
var water2 = document.querySelector('#water2');
water2.addEventListener("webkitAnimationEnd", function(evt){ //动画结束时事件
this.className.baseVal="runing";
water1.className.baseVal="runing";
}, false);
water1.addEventListener("webkitAnimationEnd", function(evt){ //动画结束时事件
this.style.strokeDashoffset=0;
}, false);
keybtn.addEventListener("click", function(){
water2.className.baseVal="first-run";
}, false);
function change(){
var svgHtml=document.getElementById("div").innerHTML.trim();
var canvasId=document.getElementById("canvasId");
canvg(canvasId,svgHtml);
}
function downloadByBlob(blobObj,filename) {
const link = document.createElement('a');
link.style.display = 'none';
const downloadUrl = window.URL.createObjectURL(blobObj);
link.href = downloadUrl;
link.download = `test.png`;
document.body.appendChild(link);
link.click();
link.remove();
}
//1.将div转成svg
function save(){
var divContent = document.getElementById("div").innerHTML.trim();
var data = "data:image/svg+xml," +
"" +
"" +
"" +
divContent +
"" +
"" +
"";
var img = new Image();
img.src = data;
document.getElementsByTagName('body')[0].appendChild(img);
//2.svg转成canvas
var canvas = document.createElement('canvas'); //准备空画布
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d'); //取得画布的2d绘图上下文
context.drawImage(img, 0, 0);
//3. 图片导出为 png 格式
var filename = 'file_' + (new Date()).getTime() + '.' + "png";
//var imgData = canvas.toDataURL(type);
canvas.toBlob(function(blob) {
var url = URL.createObjectURL(blob);
//downloadByBlob(blob,filename);
var newImg = document.createElement("img");
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
});
}
传输和编码
保存成png以后,在内存里面就可以直接传输到客户端进行编码,当然也可以使用canvas的capturestream方法,保存成h264 传输到服务器,或者进行rtsp,rtmp协议进行传输。这一部分对前端来讲可能不一定清楚,但是能做的事情很多。传输到后台使用websocket协议,也可以使用webrtc的rtp传输。后面继续添加编写 图为笔者使用这种方式在web上面直接投屏到大屏上,为web增加两个按钮,一个投屏,一个取消投屏,选择大屏电视后直接由web传输到了大屏上。期间经过了upnp协议,ssdp协议,http协议,websocket,rtp协议等等传输,有兴趣可以一起探讨。