解決了第一個問題圖像灰度處理以後,接着就是作擦除的效果。javascript
一開始想到 Canvas 的畫布能夠相互覆蓋的特性,彩色原圖做爲背景,灰度圖渲染到 Canvas 畫布上,而後手指滑動的時候,把接觸的部分清除掉,就顯示出了背景圖。關鍵的部分是怎麼清除畫布上已有圖像,查詢資料發現有兩種方式:html
destination-out
時效果以下:在上面兩種方式中,第一種方式正是功能實現所須要的,但擦除時的邊角效果沒有第二種方式理想。下面以第二種方式做爲示例。html5
在實現的過程當中,發現有幾點須要注意:java
globalCompositeOperation
屬性設置的時機,過早設置,可能畫布上沒法顯示內容。這是示例頁面,移動端訪問以下:git
通常用戶都不會所有進行擦除,並且這種體驗也很差,因此擦除面積達到必定百分比時,自動擦除剩餘的部分。github
擦除效果其實是改變了已有圖像的透明度,能夠經過 getImageData 方法查看 Canvas 上圖像的像素數據。經過統計符合透明度要求的像素所佔百分比,就等效擦除面積的百分比。至於透明度多少算擦除有效,看實際應用場景和所需效果。下面是主要的實現:canvas
/** * 獲取透明所佔百分比,返回一個 <= 1 的值 * @param {object} context canvas 上下文對象 * @param {number} opacity 透明度參考值,初始參考透明值是 128 */
function getOpacityPercentage (context, opacity = 128) {
var imageData = context.getImageData(0,0,248,415);
var colorDataArr = imageData.data;
var colorDataArrLen = colorDataArr.length;
var eraseArea = [];
// rgba 顯示的模式,因此一個像素表示有 4 個份量,透明度是最後一個份量
for(var i = 0; i < colorDataArrLen; i += 4) {
// 嚴格上來講,判斷像素點是否透明須要判斷該像素點的 a 值是否等於0,
if(colorDataArr[i + 3] < opacity) {
eraseArea.push(colorDataArr[i + 3]);
}
}
var divResult = eraseArea.length / (colorDataArrLen/4);
// 處理除不盡的狀況
var pointIndex = String(divResult).indexOf('.');
if (pointIndex>-1) {
divResult = String(divResult).slice(0,pointIndex+5);
}
return Number(divResult).toFixed(2);
}
複製代碼
這是示例頁面,移動端訪問以下:post
優化一中擦除所有的效果是一會兒就不見了,但我在那個遊戲裏面看到的擦除效果是有一個過程的。因而再折騰了一下。優化
這是示例頁面,移動端訪問以下:ui
必應首頁圖片有些時候蠻不錯的。