最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS如何實(shí)現(xiàn)頁面截屏功能實(shí)例代碼

 更新時(shí)間:2021年06月15日 10:51:48   作者:一個(gè)per  
這篇文章主要給大家介紹了關(guān)于JS如何實(shí)現(xiàn)頁面截屏功能的相關(guān)資料,文中主要利用了html2canvas和canvas繪制兩個(gè)方法來實(shí)現(xiàn),需要的朋友可以參考下

"頁面截屏"是前端經(jīng)常遇到的需求,比如頁面生成海報(bào),彈窗圖片分享等,因?yàn)闉g覽器沒有原生的截圖API,所以需要借助canvas來實(shí)現(xiàn)導(dǎo)出圖片實(shí)現(xiàn)需求。

可行性方案

  1. 方案1: 將 DOM 改寫成 canvas ,調(diào)用canvas的toBlob或者toDataURL方法即刻上傳到七牛云或服務(wù)器
  2. 方案2: 使用第三方庫html2canvas.js實(shí)現(xiàn) canvas , 在不更改頁面已有DOM的情況下優(yōu)雅生產(chǎn)canvas

解決方案的選擇

方案1:需要手動計(jì)算每個(gè)DOM元素的Computed Style,然后需要計(jì)算好元素在canvas的大小位置等屬性。

方案1難點(diǎn)

  • 需要棄用已有的html頁面,改用canvas重寫。
  • 頁面結(jié)構(gòu)層復(fù)雜的情況下用canvas寫,不易重構(gòu)。
  • 有一定canvas基礎(chǔ)。

方案2:該項(xiàng)目在Github上stars已有兩萬多start,作者仍在積極維護(hù)。API非常簡單,在已有項(xiàng)目中開箱即用。

html2canvas

因?yàn)槭浅R姷男枨?,所以社區(qū)會有成熟的解決方案,首先試試社區(qū)的解決方案。

<div id="capture" style="padding: 10px; background: #f5da55">
    <h4 style="color: #000; ">Hello world!</h4>
</div>
html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas)
});

以上是官網(wǎng)的實(shí)例用法。在網(wǎng)頁上出現(xiàn)了一個(gè)新的 canvas DOM。接下來我們只需要把canvas轉(zhuǎn)換成圖片就好。這里使用canva原生的toDataURL和toBlob方法上次到七牛云。

使用時(shí)需要注意。此處如果生產(chǎn)的畫布中有跨域圖片,需要配置allowTaint為true。

如果是原生canvas實(shí)現(xiàn),canvas需要所有跨域圖片請求完成才可繪制。有兩種解決方案

  • 方案1:在html上寫好img標(biāo)簽,src寫好對應(yīng)的圖片url。缺點(diǎn)很明顯,會污染頁面的布局結(jié)構(gòu)。
  • 方案2:使用js,使用new Image()的方式。設(shè)置src到對應(yīng)的圖片url,在onload回調(diào)中處理相關(guān)操作。優(yōu)點(diǎn):可行性最高,不過有回調(diào)地獄的問題。我們用Promise改寫一下
function asyncImage(url) {
    const img = new Image();
    img.src = url;
    img.setAttribute('crossOrigin', 'anonymous');
    return new Promise((resolve, reject) => {
        img.onload = () => resolve(img);
        img.onerror = reject;
    });
}

好的,大功告成~是不是可以交付需求了呢?開開心心提測,但是在移動端測試的時(shí)候發(fā)現(xiàn)生產(chǎn)的圖片非常模糊。這樣是不行的,明顯low了許多(測試不給過orz)。

github有相應(yīng)的解決方案 傳送門 ,這個(gè)回答也是解決很多人的問題

基本原理:將canvas寬高放大兩倍。把css把canvas的style設(shè)置成1倍大小。

    var shareContent = YourTargetElem; 
    var width = shareContent.offsetWidth; 
    var height = shareContent.offsetHeight; 
    var canvas = document.createElement("canvas"); 
    var scale = 2 || window.devicePixelRatio ; //也可以使用設(shè)備像素比

    canvas.width = width * scale; 
    canvas.height = height * scale; 
    canvas.getContext("2d").scale(scale, scale); 

    var opts = {
        scale: scale, 
        canvas: canvas, 
        logging: true, 
        width: width, 
        height: height 
    };
    html2canvas(shareContent, opts).then(function (canvas) {
        var context = canvas.getContext('2d');

        var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height);

        document.body.appendChild(img);
        $(img).css({
            "width": canvas.width / 2 + "px",
            "height": canvas.height / 2 + "px",
        })
    });

原理我們已經(jīng)知道了,實(shí)際操作之后圖像也確實(shí)清晰了很多。但是問題還是沒有解決掉。

縮小雖然提高了清晰度,但是我們需要的圖片是原始比例的大小。。

最終多次嘗試無果后,選擇放棄使用框架。直接用原生canvas擼一個(gè)!

canvas繪制

我們知道,在高清屏的設(shè)備下,任何繪制canvas中的圖像、文字、線條、形狀都可能會出現(xiàn)模糊的問題??赏ㄟ^引入 GitHub 中的 hidpi-canvas 有效地解決。

  1. 首先去 GitHub 下載 hidpi-canvas.js 文件:傳送門;
  2. 在項(xiàng)目中引入 hidpi-canvas.js 文件;
  3. 調(diào)用 getPixelRatio() 函數(shù),得到 ratio 值;
  4. 在 drawImage() 中,將 width 和 height 乘以 ratio;
  5. 最終的canvas導(dǎo)出為Blog,轉(zhuǎn)換成文件對象上傳七牛云。

核心代碼如下

    function asyncImage(url) {
        const img = new Image();
        img.src = url;
        img.setAttribute('crossOrigin', 'anonymous');
        return new Promise((resolve, reject) => {
            img.onload = () => resolve(img);
            img.onerror = reject;
        });
    }
    async function drawCanvas(){
        var canvas = document.querySelector('canvas');
        var context = canvas.getContext('2d');
        var ratio = getPixelRatio(context);  // 關(guān)鍵代碼
        canvas.width = 300 * ratio; // 畫布寬度
        canvas.height = 300 * ratio; // 畫布高度
        var divWidth = 300 * ratio; // 用于內(nèi)容居中
        var divHeight = 300 * ratio; // 用于內(nèi)容居中
        const image = await asyncImage('picUrl')
        const imgWidth = 550
        const imgHeight = 300
        context.drawImage(this, 50, 50, imgWidth * ratio, imgHeight * ratio)
        // Some other code
        const Blob = canvas.toBlob((Blob)=>{
            //上傳七牛云
        });
    } 

最終生成的圖片終于清晰了...只需要根據(jù)dom的offsetWidth等適配不同屏幕就可以了。

總結(jié)

如果對圖片的清晰度要求不高,或者圖片需求是生成縮略圖的情況下。采用 html2canvas 是非常不錯(cuò)的選擇。
否則,還是用canvas繪制出的圖片更清晰。

到此這篇關(guān)于JS如何實(shí)現(xiàn)頁面截屏功能的文章就介紹到這了,更多相關(guān)JS頁面截屏功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何在JavaScript?中獲取域名

    如何在JavaScript?中獲取域名

    本文將討論如何使用?JavaScript?事件和函數(shù)在網(wǎng)頁執(zhí)行期間以編程方式獲取域名,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-06-06
  • js使用xml數(shù)據(jù)載體實(shí)現(xiàn)城市省份二級聯(lián)動效果

    js使用xml數(shù)據(jù)載體實(shí)現(xiàn)城市省份二級聯(lián)動效果

    這篇文章主要為大家詳細(xì)介紹了js使用xml數(shù)據(jù)載體實(shí)現(xiàn)城市省份二級聯(lián)動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 用js實(shí)現(xiàn)簡單算法的實(shí)例代碼

    用js實(shí)現(xiàn)簡單算法的實(shí)例代碼

    下面小編就為大家?guī)硪黄胘s實(shí)現(xiàn)簡單算法的實(shí)例代碼。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-09-09
  • webpack5 常用插件使用問題小結(jié)

    webpack5 常用插件使用問題小結(jié)

    webpack 是一個(gè)模塊打包器,這篇文章主要介紹了webpack5 常用插件使用問題小結(jié),每次打包完都需要手動刪除掉dist文件目錄,使用CleanWebpackPlugin就可自動清除dist目錄,感興趣的朋友跟隨小編一起看看吧
    2024-02-02
  • JavaScript設(shè)置IFrame高度自適應(yīng)(兼容各主流瀏覽器)

    JavaScript設(shè)置IFrame高度自適應(yīng)(兼容各主流瀏覽器)

    IFrame高度的設(shè)置問題一直都是前端的噩夢而且還要兼容各主流瀏覽器更是難上加難了,下面與大家分享下一個(gè)不錯(cuò)的技巧,感興趣的你可以參考下哈
    2013-06-06
  • 發(fā)布一個(gè)高效的JavaScript分析、壓縮工具 JavaScript Analyser

    發(fā)布一個(gè)高效的JavaScript分析、壓縮工具 JavaScript Analyser

    發(fā)布一個(gè)高效的JavaScript分析、壓縮工具 JavaScript Analyser...
    2007-11-11
  • ES6/JavaScript使用技巧分享

    ES6/JavaScript使用技巧分享

    本篇文章主要給大家講解了ES6/JavaScript使用技巧,需要的朋友參考一下吧。
    2017-12-12
  • 用js實(shí)現(xiàn)博客打賞功能

    用js實(shí)現(xiàn)博客打賞功能

    經(jīng)常在一些博客中看到有一個(gè)打賞功能,本篇文章主要介紹了博客打賞功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-10-10
  • JavaScript使用prototype屬性實(shí)現(xiàn)繼承操作示例

    JavaScript使用prototype屬性實(shí)現(xiàn)繼承操作示例

    這篇文章主要介紹了JavaScript使用prototype屬性實(shí)現(xiàn)繼承操作,結(jié)合實(shí)例形式詳細(xì)分析了JavaScript使用prototype屬性實(shí)現(xiàn)繼承的相關(guān)原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下
    2020-05-05
  • 詳解JavaScript對象的深淺復(fù)制

    詳解JavaScript對象的深淺復(fù)制

    從層次上來看,對象的復(fù)制可以簡單地分為淺復(fù)制和深復(fù)制,顧名思義,淺復(fù)制是指只復(fù)制一層對象的屬性,不會復(fù)制對象中的對象的屬性,對象的深復(fù)制會復(fù)制對象中層層嵌套的對象的屬性。本文是我在復(fù)制對象方面的一些心得總結(jié),由淺復(fù)制到深復(fù)制,感興趣的朋友一起學(xué)習(xí)吧
    2017-03-03

最新評論

苗栗市| 林芝县| 土默特右旗| 清流县| 温宿县| 巩义市| 桦甸市| 田东县| 岗巴县| 罗田县| 曲靖市| 桐乡市| 万盛区| 斗六市| 敖汉旗| 靖江市| 叙永县| 宝兴县| 西乡县| 博乐市| 青川县| 沙坪坝区| 呼玛县| 铁岭市| 唐海县| 琼结县| 安陆市| 含山县| 临洮县| 洪湖市| 游戏| 长宁区| 松江区| 安龙县| 通江县| 海宁市| 南木林县| 大余县| 巴马| 青川县| 黔西县|