H5 中html 頁面存爲圖片並長按 保存

最近接到的一個新需求:頁面一個靜態H5,中間有一頁是輸入信息,而後跳轉到最後一頁,自動將頁面生成圖片,用戶能夠長按圖片保存到手機上。

展現一下最後一頁的樣子:html

 

剛拿到這個需求,在網上看了不少文章,最廣泛的是使用 html2canvas + canvas2image  來實現。因而,跟着前人的腳步,踏上了一個不斷採坑採坑採坑的旅程。ios

下面直接描述我在作這個需求過程當中遇到的問題以及解決辦法吧:canvas

1.html2canvas 圖片跨域:

這個問題網上不少解決辦法:跨域

這個是最經常使用的, 剛開始我只是加了紅色框裏面的這一句,可是並無任何做用,依舊報錯。後來看到有人說,加上前面那一句,因此果斷在加進去。瀏覽器

這兩句其實表達的是同一個意思:容許圖片跨域。緩存

固然,也有網友說,直接給一個空值就能夠,我當時試了一下,並不ok~~~~.服務器

 

 

2.屢次使用canvas drawImage 方法圖片展現問題

2.1 圖片加載順序問題

在我這個需求裏面,確定是文字描述以及二維碼是展現在圖片上面的,剛開始我是網絡

1. drawImage   文字,函數

2. drawImage    二維碼測試

3. drawImage   背景大圖

然而,結果讓我大吃一驚,只有背景圖加載渲染出來了。而後,經過無所不能的網絡才知道:drawImage 的順序應該是:圖片最底下的須要最早加載渲染。

2.2 圖片顯示不完整

在2.1 問題出現的同時還遇到了這個問題,圖片渲染不完整,這。。nima。。。需求才剛開始作,怎麼這樣爲難一個小女子。。。

不過有問題嘛,就解決咯。

圖片渲染不完整,緣由就是:在圖片尚未加載完成的時候,canvas 就開始進行渲染。

 所以解決辦法就是:等圖片加載完成後再進行drawImage 操做就能夠啦,上~~~~代碼:

 

 

3.canvas 保存爲圖片的跨域問題

遇到這個問題,我真的是花了一堆一堆的時間來看文章,看博客,,。

這會萬能的網友給個人解決辦法並無任何效果:

他們說:1.把圖片取下來放在本身服務器上(我用的公司的圖片服務器。可是和個人放代碼服務器不是同一個地址啊)

2. 用canvas2Image 啊,然而,,這不也是跨域麼,,並無啥,,用。

3.還有啥來着,,忘了,反正那天搞得我精神崩潰,,,也沒解決到問題,,後來實在忍不住,問了公司的大神:大神說:你用base64 的呢。。

一語驚喜夢中人,對啊,這種方法多棒,這樣就不會跨域了啊。當時爲了趕進度,直接在線吧圖片轉成basa64  ,而後存成一個js 文件。

當時是這樣的:紅框裏表示的是文件的格式。。、

 

至此,個人html 已經轉爲canvas  而且從canvas 轉爲img 存在頁面上了,,

 

後來我在看這一段,以爲彷佛不太好,這個文件顯得很大,因此我想在用這個文件的時候在把它轉成base64 的格式,,

1.利用canvas todataUrl 將圖片轉爲base64

可是這種方法不可避免的會出現跨域的問題,pass

2.base64.js  

這個文件中中文轉碼會出問題,並且我試過了,基本的字符串轉碼都是ok 的,可是對於文件轉碼就會出問題

3.瀏覽器原生的而且都支持的一個東西: window.atob     and   window.btoa

window.atob  是將base64 格式轉換爲字符串或者二進制編碼格式

window.btoa  是將字符串或者二進制編碼 格式轉換爲base64  格式  因此上面的base64.js 真的,,別浪費時間精力去看了,,

那文件編碼解碼呢?

原生的也有方法:FileRender()  這個構造函數,

var reader = new FileReader();

reader.onload = function(e) {

// e.target.result

};

reader.readAsDataURL(file);

這種方法沒有測試過o(╥﹏╥)o。。

因此,目前爲止,須要把文件轉爲base64. 格式的,我並無找到合適的方法或者js 插件來操做,若是各位有什麼好的辦法,麻煩告訴我(* ̄︶ ̄)。

 

 

4. 圖片模糊而且窗口中只顯示了一部分

才定義canvas 的時候,我是給canvas 定義了一個寬高的,寬高是背景圖的大小,所以在drawImage 的時候是按照canvas 實際尺寸進行渲染。

可是轉爲圖片的時候是按照窗口的尺寸來進行的,所以圖片會模糊,若是給圖片設置canvas 寬高的話,圖片在窗口中又顯示不完整。

所以,就須要計算設備的retio,

基本思路:計算出ratio  ---> 而後canvas 轉 img (按照canvas 實際尺寸進行渲染) ---> 圖片按照窗口大小進行縮放

這個方法直接返回的是設備的ratio..

而後咱們在進行canvas 渲染的時候,

在後面進行圖片渲染的時候,圖片的寬度直接除以 ratio ,這樣圖片就能完整的顯示在窗口中。

 

 

 

5. ios10.2 canvas 轉圖片 一片黑

至此,頁面是呈現出來了,而且在個人安卓(華爲)上測試是ok

可是需求的同窗(ios)告訴我:她的手機上最後一頁是黑色的和,頂部有個白色框,,,我一懵,天,不會ios 不支持吧。

因而,用了旁邊座位同窗的手機。恩,也不行。。

啊啊啊啊啊,要崩潰。

在網上看了一下,有一種解決辦法就是:使用雙緩衝(出現黑屏的可能就是在drawImage 的時候計算量很大,而後渲染卡頓不成功)

大概思路就是:在新建一個cachecanvas 剛開始實際上是把圖片渲染在這個緩存的canvas 中的,而後在將cachecanvas 中的內容渲染到須要在頁面展現的canvas 中。

我在中間使用了一個延時,時間雖然很短,可是這樣也能確保cachacanvas 確實渲染完成在進行正式的canvas 渲染。

這樣,我周圍座位上的ios 上最後一頁都能顯示出來了,,可是那個ios10.2 的依舊不行,,啊,網上查了一下,這個版本的問題一直存在,因此,(꒦_꒦) ,

 

 就這樣,這個需求在我不斷採坑的過程當中,好像也快完結了,這裏不多直接貼代碼進來,由於貼進來彷佛看的不太好,因此我基本上是截圖的。

 

最後,幾個小tips :

1.直接將網頁圖片存成base64 格式的,若是圖片不多,能夠,若是圖片不少,仍是建議不要這麼操做了,比較一個base64的數據格式就已經很大了。。。

2.圖片先壓縮,而後在進行base64格式編碼吧

3.對於drawImage 的位置,是相對於canvas  實際尺寸的。因此若是使用百分比,建議先獲得窗口的寬高,而後在進行賦值。

4. 在使用canvas   fillText 的時候,有一個限制最大寬度,就是fillText 的最後一個參數(直接寫數值便可,不用帶單位,默認彷佛是px)。

5.對於通常的H5,仍是對圖片進行預加載一下吧,。。(網上不少圖片預加載的方法,自行查找哦)。

相關文章
相關標籤/搜索