最近做有關(guān)three.js的動畫眷唉,想通過截圖然后在新的頁面打開截圖予颤,并且想把圖片下載到本地,連環(huán)坑很ok??嗯冬阳。這個必須要記下來蛤虐!
先來看看普通頁面的截圖
一開始看到這個,完全沒思路肝陪,普通的html標(biāo)簽要怎么才能變成一張圖驳庭??氯窍?饲常,其實嘞,目前的截圖方案都并不是我們理解的那種截圖狼讨,不管是使用canvas還是svg贝淤,其實都是做了轉(zhuǎn)化,但是這兩種方法都不在這詳細(xì)描述了政供,有興趣的可以看看這篇播聪,說的很詳細(xì)了(canvas VS svg 截圖),然鵝鲫骗,肯定是有工具的啦犬耻,那就是git上開源的 html2canvas,有好多小星星呀执泰,并且使用超簡單枕磁,但是原理也是將html的標(biāo)簽重新繪制到canvas中,其中也有很多不能解決的問題术吝,比如什么文本陰影啊计济,豎版圖片啊之類的,還有E挪浴沦寂!動畫元素截取不出來!L匝谩4亍!!,截屏出來是白屏毯侦。
怎么解決嘞
-
為什么是白屏:
截取three.js 渲染的圖哭靖,如果直接將輸出的canvas變成圖片是無法獲取的,因為在獲取之前渲染界面是清空的狀態(tài)侈离,所以需要在渲染之后清空之前將渲染的內(nèi)容轉(zhuǎn)換為圖片试幽,即將場景的內(nèi)容渲染一遍并將渲染的內(nèi)容轉(zhuǎn)為圖片數(shù)據(jù)。
-
解決方案:
shot(){
let image = new Image();
renderer.render(scene, camera);//renderer為three.js里的渲染器卦碾,scene為場景 camera為相機
let imgData = renderer.domElement.toDataURL("image/jpeg");//這里可以選擇png格式j(luò)peg格式
image.src = imgData;
document.body.appendChild(image);//這樣就可以查看截出來的圖片了
}
-
劃重點:
其實就是相當(dāng)于渲染一幀铺坞,并把這一幀輸出
而如果需要截某個部分的圖片,只需要將相機變一下洲胖,換成自己想要范圍济榨,并渲染一幀再截屏出來。
優(yōu)點非常明顯宾濒, 這樣相當(dāng)于重新渲染一幀腿短,即便是截取某個很小的部分,截取的圖片也是很清晰的绘梦。
截完圖之后嘞
我想要的呢是將截的圖展示在新的頁面上橘忱,可是生成的圖片并不是base64的碼,所以我們要將渲染的canvas轉(zhuǎn)化為base64的圖片,toDataURL可以直接做到卸奉,然后展示在新窗口就好啦钝诚。
function debugBase64(base64URL){
let win = window.open();
win.document.write('<image id="IframeReportImg" src="' + base64URL + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen ></image>');
}
圖片下載
還是基于瀏覽器的功能去操作的
function downloadImage(imgUrl) {
let a = $("<a></a>").attr("href", imgUrl).attr("download", "img.png").appendTo("body");
a[0].click();
a.remove();
}
其中的imgUrl就是我們之前轉(zhuǎn)好的碼,也就是
let imgData = renderer.domElement.toDataURL("image/jpeg");/
這里的imgData榄棵。