最近做了個需求,設計提供幾張切圖。前端把切圖還有後臺返回的文字資訊,拼接到一塊繪製為一張圖片。然後會下載、或者上傳。 做起來其實還是挺簡單的。下面說下大概的流程。
前端繪圖只能使用 canvas。
1、主要用到的canvas API 有以下幾個:
let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
// 設定填充顏色,也可以設定字型顏色
ctx.fillStyle = bgcColor;
// 設定文字資訊。字型、大小、font-weight等。
ctx.font = 'bold 20px 宋體';
// 設定文字對齊方式
ctx.textAlign = 'center'; // left || right || center || start || end; 總共五個值,常用left、center;
// 設定文字基線對齊方式 類似於css的 vertical-align
ctx.textBaseLine = 'middle'; // top || hanging || middle || alphabetic || ideographic || bottom
// 繪製文字 text: 文字內容。x: 文字的X座標。y: 文字的Y座標。maxWidth: 繪製文字的最大寬度。
ctx.fillText(text, x, y, maxWidth);
// 計算文字所佔的寬度 這個方法返回一個物件,有個 width 屬性。
ctx.measureText(text)
// 繪製矩形
ctx.fillRect(0, 0, width, height);
// 繪製圖片 img: 目標圖片。x: X座標。y: Y座標。width:繪製的寬度。height:繪製的高度。
ctx.drawImg(img, x, y, width, height);
// 繪製圓
ctx.arc()
複製程式碼
canvas的詳情參考 https://www.w3cplus.com/blog/tags/616.html
2、使用canvas 繪圖完畢後。提供匯出下載
canvas 有兩個API。可以把繪製的圖片轉為可下載的檔案。
canvas.toDataURL() 方法返回一個包含圖片展示的 dataURL。可以使用 type 引數設定型別。預設為 PNG 格式。圖片的解析度為 96dpi;
* 如果畫布的高度或寬度 為0 那麼會返回字串 “data:,”
* 如果傳入的型別非"image/png",但是返回的值以"data:image/png"開頭,那麼該型別是不支援的。
* chrome 支援 "image/webp"型別
複製程式碼
語法
canvas.toDataURL(type, encoderOptions);
複製程式碼
引數
type: 圖片格式。預設為 image/png;
encoderOptions: 在指定的格式為 'image/jpeg'、'image/webp'的情況下,可以設定從0 - 1 的值來改變圖片的質量。
如果超出取值範圍會設定為 0.92 。其他引數會忽略
複製程式碼
返回值
返回一個 包含 dataURL 的 DOMString (也就是base64);
複製程式碼
如何下載
// 下載方法。
/**
*@param imgSrc 檔案連結可以是一個dataURL 也可以是一個 blob 物件。
*@param imgName 下載後的檔名字。
*/
function downloadImg (imgSrc, imgName) {
let elem = document.createElement('a');
elem.setAttribute('href', imgSrc);
elem.setAttribute('download', imgName);
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
複製程式碼
看了上面這些方法之後,這個需求就比較簡單了
let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
.....
//圖片繪製完成
let imgSrc = ctx.toDataURL('image/jpeg', 0.9);
let imgName = '測試圖片.jpg';
downloadImg(imgSrc, imgName); // 瀏覽器就會自動下載了
複製程式碼
一開始,我用的就是上面這種方法下載,不過當繪製下載一個比較大的圖片時,瀏覽器就會提示下載失敗。查了資料,原來使用dataURL進行下載會有大小限制。後來再次查資料發現可以使用 blob 進行下載。
關於blob的詳情請參考:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
瞭解一下,canvas 如何轉為 blob
語法
canvas.toBlob(callback, type, encoderOption);
複製程式碼
引數
callback: 因為canvas 如何轉為 blob是一個非同步操作,所以需要一個回撥函式,引數就是 blob物件。
type: 指定圖片格式。預設為: 'image/png';
encoderOption: 在指定的格式為 'image/jpeg'、'image/webp'的情況下,可以設定從0 - 1 的值來改變圖片的質量。
如果超出取值範圍會設定為 0.92 。其他引數會忽略
複製程式碼
這個方法沒有返回值。
好了,現在看下如何使用 blob 進行下載
let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
.....
// 圖片繪製完成
ctx.toBlob(function (blob) {
let imgSrc = window.URL.createObjectURL(blob);
let imgName = '測試圖片.jpg';
downloadImg(imgSrc, imgName);
window.URL.revokeObjectURL(imgSrc);
}, 'image/jpeg', 0.9)
複製程式碼
有兩個方法,之前沒有了解過,今天就記錄一下。\
URL.createObjectURL()
看到MDN上對這個方法的介紹,這是一個實驗中的功能,某些瀏覽器尚在開發中。該標準對應的文件可能被重新修訂,所以在未來版本的瀏覽器中,該功能的語法和行為也可能改變。(這些東西,以後再說,現在是管不了那麼多了。都怪產品^_^)。
URL.createObjectURL()
靜態方法會建立一個 DOMString
,其中包含一個表示引數中給出的物件的URL。這個URL的生命週期和建立它的視窗中的 document
繫結。這個新的URL物件表示指定的File
物件或Blob
物件。
語法
objectURL = URL.createObjectURL(blob); // window可以省略
複製程式碼
引數
用來建立URL的 File
或 Blob
物件。
注意事項
在每次呼叫URL.createObjectURL(blob)
方法時,都會建立一個新的URL物件,儘管已經用相同的引數建立過。所以,當不再需要這個URL物件時,必須通過呼叫URL.revokeObjectURL()
方法來釋放。瀏覽器會在文件退出的時候,釋放它們,不過為了獲得最佳使用效能以及記憶體狀況,你應該在安全的時機主動釋放它們。
URL.revokeObjectURL()
URL.revokeObjectURL()
靜態方法用來釋放一個之前通過呼叫URL.createObjectURL(blob)
方法生成的URL物件。
語法
window.URL.revokeObjectURL(objectUrl)
複製程式碼
引數
objectUrl: URL.createObjectURL(blob)方法生成的URL物件;
複製程式碼
今天先記錄下如何下載。明天記錄下如何上傳圖片