展現一下最後一頁的樣子:html
剛拿到這個需求,在網上看了不少文章,最廣泛的是使用 html2canvas + canvas2image 來實現。因而,跟着前人的腳步,踏上了一個不斷採坑採坑採坑的旅程。ios
下面直接描述我在作這個需求過程當中遇到的問題以及解決辦法吧:canvas
這個問題網上不少解決辦法:跨域
這個是最經常使用的, 剛開始我只是加了紅色框裏面的這一句,可是並無任何做用,依舊報錯。後來看到有人說,加上前面那一句,因此果斷在加進去。瀏覽器
這兩句其實表達的是同一個意思:容許圖片跨域。緩存
固然,也有網友說,直接給一個空值就能夠,我當時試了一下,並不ok~~~~.服務器
在我這個需求裏面,確定是文字描述以及二維碼是展現在圖片上面的,剛開始我是網絡
1. drawImage 文字,函數
2. drawImage 二維碼測試
3. drawImage 背景大圖
然而,結果讓我大吃一驚,只有背景圖加載渲染出來了。而後,經過無所不能的網絡才知道:drawImage 的順序應該是:圖片最底下的須要最早加載渲染。
在2.1 問題出現的同時還遇到了這個問題,圖片渲染不完整,這。。nima。。。需求才剛開始作,怎麼這樣爲難一個小女子。。。
不過有問題嘛,就解決咯。
圖片渲染不完整,緣由就是:在圖片尚未加載完成的時候,canvas 就開始進行渲染。
所以解決辦法就是:等圖片加載完成後再進行drawImage 操做就能夠啦,上~~~~代碼:
遇到這個問題,我真的是花了一堆一堆的時間來看文章,看博客,,。
這會萬能的網友給個人解決辦法並無任何效果:
他們說: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 插件來操做,若是各位有什麼好的辦法,麻煩告訴我(* ̄︶ ̄)。
才定義canvas 的時候,我是給canvas 定義了一個寬高的,寬高是背景圖的大小,所以在drawImage 的時候是按照canvas 實際尺寸進行渲染。
可是轉爲圖片的時候是按照窗口的尺寸來進行的,所以圖片會模糊,若是給圖片設置canvas 寬高的話,圖片在窗口中又顯示不完整。
所以,就須要計算設備的retio,
基本思路:計算出ratio ---> 而後canvas 轉 img (按照canvas 實際尺寸進行渲染) ---> 圖片按照窗口大小進行縮放
這個方法直接返回的是設備的ratio..
而後咱們在進行canvas 渲染的時候,
在後面進行圖片渲染的時候,圖片的寬度直接除以 ratio ,這樣圖片就能完整的顯示在窗口中。
至此,頁面是呈現出來了,而且在個人安卓(華爲)上測試是ok
可是需求的同窗(ios)告訴我:她的手機上最後一頁是黑色的和,頂部有個白色框,,,我一懵,天,不會ios 不支持吧。
因而,用了旁邊座位同窗的手機。恩,也不行。。
啊啊啊啊啊,要崩潰。
在網上看了一下,有一種解決辦法就是:使用雙緩衝(出現黑屏的可能就是在drawImage 的時候計算量很大,而後渲染卡頓不成功)
大概思路就是:在新建一個cachecanvas 剛開始實際上是把圖片渲染在這個緩存的canvas 中的,而後在將cachecanvas 中的內容渲染到須要在頁面展現的canvas 中。
我在中間使用了一個延時,時間雖然很短,可是這樣也能確保cachacanvas 確實渲染完成在進行正式的canvas 渲染。
這樣,我周圍座位上的ios 上最後一頁都能顯示出來了,,可是那個ios10.2 的依舊不行,,啊,網上查了一下,這個版本的問題一直存在,因此,(꒦_꒦) ,
就這樣,這個需求在我不斷採坑的過程當中,好像也快完結了,這裏不多直接貼代碼進來,由於貼進來彷佛看的不太好,因此我基本上是截圖的。
1.直接將網頁圖片存成base64 格式的,若是圖片不多,能夠,若是圖片不少,仍是建議不要這麼操做了,比較一個base64的數據格式就已經很大了。。。
2.圖片先壓縮,而後在進行base64格式編碼吧
3.對於drawImage 的位置,是相對於canvas 實際尺寸的。因此若是使用百分比,建議先獲得窗口的寬高,而後在進行賦值。
4. 在使用canvas fillText 的時候,有一個限制最大寬度,就是fillText 的最後一個參數(直接寫數值便可,不用帶單位,默認彷佛是px)。
5.對於通常的H5,仍是對圖片進行預加載一下吧,。。(網上不少圖片預加載的方法,自行查找哦)。