網頁長按儲存及識別二維碼

山頭人漢波發表於2022-07-13

網易噠噠的 H5 一向是業界精品,其中不少 H5 會成為爆款,能在朋友圈廣泛流傳的那種。同時,他們還寫了一本很水的書——製造爆款:H5營銷策劃一本通,草草介紹了下各式各樣的H5,但相關的技術文章卻都沒這麼介紹,筆者一直想仿做類似的H5,找來找去,也只找到兩篇網易同廠的技術類文章:

就此,筆者做個簡易H5,介紹一下個人認為H5中比較重要的功能點——長按儲存圖片及識別二維碼

此專案主要用到三個庫

前期準備

設計稿:魔改公司H5中的其中一頁

字型:尋找開源字型,這款不錯——LXGW WenKai / 霞鶩文楷

此外,就是佈局,筆者在移動端法門:自適應方案和高清方案 中闡述過一個觀點:

不同的佈局方式作用不同,像新聞類的H5,採用 px 為單位,是為了讓大手機看到更多的資訊;像應用型的H5,採用 rem/vw 為單位,力求在各種手機上能保持一致UI

像營銷頁面,是希望在各種手機上保持UI一致,理論上採用 rem/vw 是沒問題的,但是 ggvswild 在高質量前端快照方案:來自頁面的「自拍」 中曾說:

為了給到html2canvas明確的整數計算值,避免因小數舍入而導致的拉伸模糊,建議將佈局中使用中使用%vwvhrem等單位的元素樣式,統一改為使用px

而筆者在實際專案開發時,採用 rem 為單位並沒有發現拉伸模糊問題。除此之外,筆者又尋找了幾個網易的 H5

個人總結:在佈局上它們都使用絕對定位佈局,在長度單位上各有特色,所以做 H5 佈局是無所謂用那種方式,只要在截圖頁不讓元素拉伸即可,也就是說如果拉伸模糊了,可查一下此元素的單位是否是小數,至於其他頁的佈局,習慣用那個就用那個

實戰開始

字型的運用

字型「 霞鶩文楷」大約4.4M,太大了,用 fontmin 提取用到的字型,這裡我直接使用 Fontmin 的客戶端,無它,命令列執行出錯,營銷頁只用到了9個漢字,裁剪後從4.4M減少到 44kb

二維碼功能的實現

很簡單,看文件就能學會

var qrcode = document.getElementById("qrcode")
new QRCode(qrcode, {
    width: 200,
    height: 200,
    colorDark: "#000000",
    colorLight: "#ffffff",
    correctLevel: QRCode.CorrectLevel.L
}).makeCode(window.location.href)

快照實現

將 html2canvas 和 canvas2image 結合,將 HTML 轉成 base64 圖片,而這一功能可以做成一個庫:

var convertToImage = (function () {

    function createBaseCanvas(scale, width, height) {
        const canvas = document.createElement('canvas');

        canvas.width = width * scale;
        canvas.height = height * scale;

        const context = canvas.getContext("2d");

        // 關閉抗鋸齒
        context.mozImageSmoothingEnabled = false;
        context.webkitImageSmoothingEnabled = false;
        context.msImageSmoothingEnabled = false;
        context.imageSmoothingEnabled = false;

        context.scale(scale, scale);

        return canvas;
    }

    function convertToImage(container, options = {}) {
        const scale = window.devicePixelRatio;

        const width = container.offsetWidth;
        const height = container.offsetHeight;

        const canvas = createBaseCanvas(scale, width, height);

        const ops = {
            useCORS: true, // 如果截圖的內容裡有圖片,解決檔案跨域問題
            allowTaint: false, // 是否允許跨源影像汙染畫布
            ...options
        };

        return html2canvas(container, ops).then(canvas => {
            const imageEl = Canvas2Image.convertToPNG(canvas, canvas.width, canvas.height)
            return imageEl
        })
    }
    return convertToImage
})()

使用:

 convertToImage(document.querySelector("#capture")).then((imageEl) => {
     document.getElementsByClassName("save")[0].appendChild(imageEl)
 })

canvas2image 的坑點

  1. 最新版本(1.4.1)已支援縮放,已解決圖片不清晰的問題

    • 圖片不清晰以前是個大問題,不少博文都有對其說明,目前的版本沒看到模糊
  2. 文件上寫支援 background-image:linear-gradient(),但是如果是漸變至透明是不行的

漸變背景色

而我希望呈現這樣的樣式:

背景圖

背景漸變方案:

background-image: linear-gradient(90deg, $white, transparent);

改成背景圖:

background: url('../bg.png') no-repeat;
background-size: 100% 100%;
  1. 文字會出現位移,這個問題至今一直存在,作者也沒有修復

以上就是所遇到的問題,像跨域之類的問題,隨著時間的推移,文件上都有說明,已經不是什麼問題

線上預覽地址:這裡

參考資料

相關文章