最近、AlipayのJifuキャラクターが殺到しています
まだJingyefuに会えてないんですค(TㅅT)とても傷心しています
今日はモバイルのスクラッチオフアプリをお届けします
効果はこんな感じです
手をスワイプしてスクラッチカードをトリガーします
スクラッチカードの領域が70%以上に達すると、すべての灰色のレイヤーが自動的にスクラッチオフされます
コードはそれほど多くありません
コードはこれですべてです
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,initial-scale=1.0,user-scalable=no" name="viewport"> <title>Scrape</title> <style> #myCanvas { background-repeat: no-repeat; background-position: center; background-size: 200px 200px; } </style></head><body> <canvas id="myCanvas" width=300 height=300></canvas> <script> var canvas = document.getElementById('myCanvas'), ctx = canvas.getContext('2d'), w = canvas.width; h = canvas.height; area = w * h; l = canvas.offsetLeft; t = canvas.offsetTop, img = new Image(); var randomImg = function(){ var random = Math.random(); if(random < 0.4){ img.src = './1.png'; }else if(random > 0.6){ img.src = './2.png'; }else{ img.src = './award.jpg'; } }; var bindEvent = function(){ canvas.addEventListener('touchmove', moveFunc, false); canvas.addEventListener('touchend', endFunc, false); }; var moveFunc = function(e){ var touch = e.touches[0], posX = touch.clientX - l, posY = touch.clientY - t; ctx.beginPath(); ctx.arc(posX, posY, 15, 0, Math.PI * 2, 0); ctx.fill(); }; var endFunc = function(e){ var data = ctx.getImageData(0, 0, w, h).data, scrapeNum = 0; for(var i = 3, len = data.length; i < len; i += 4){ if(data[i] === 0){ scrapeNum++; } } if(scrapeNum > area * 0.7){ ctx.clearRect(0, 0, w, h); canvas.removeEventListener('touchmove', moveFunc, false); canvas.removeEventListener('touchend', endFunc, false); } } var init = (function(){ ctx.fillStyle = "#ccc"; ctx.fillRect(0, 0, w, h); randomImg(); img.addEventListener('load', function(){ canvas.style.backgroundImage = 'url(' + img.src +')'; ctx.globalCompositeOperation = 'destination-out'; bindEvent(); }); })(); </script></body></html>
以下に簡単に説明します
まず、ページに必要なキャンバス要素は1つだけです
<canvas id="myCanvas" width=300 height=300></canvas>
CSSでキャンバスの背景画像のスタイルを事前に設定する必要があります
#myCanvas { background-repeat: no-repeat; background-position: center; background-size: 200px 200px;}
まず必要な変数を宣言する必要があります
var canvas = document.getElementById('myCanvas'), ctx = canvas.getContext('2d'), w = canvas.width; h = canvas.height; area = w * h; l = canvas.offsetLeft; t = canvas.offsetTop, img = new Image();
キャンバスオブジェクトとそのコンテキストオブジェクトを取得します
エリア変数は次のピクセル検出のために準備されています
imgは画像のプリロードに使用されます
最も重要な関数はinit初期化関数です
var init = (function(){ ctx.fillStyle = "#ccc"; ctx.fillRect(0, 0, w, h); randomImg(); img.addEventListener('load', function(){ canvas.style.backgroundImage = 'url(' + img.src +')'; ctx.globalCompositeOperation = 'destination-out'; bindEvent(); }); })();
プロセスは次のとおりです:
グレーのレイヤーでキャンバス全体を覆う
ランダムな写真
画像の事前読み込み
読み込み後、画像をキャンバスの背景として設定します
スクラッチする前に、ctx.globalCompositeOperation = 'destination-out';
を設定してリスニングイベントをキャンバスにバインドし、カードをペイントします
このglobalCompositeOperationはスクラッチオフゲームの鍵です
この属性を使用するには、次のことができますここをクリック
var randomImg = function(){ var random = Math.random(); if(random < 0.4){ img.src = './1.png'; }else if(random > 0.6){ img.src = './2.png'; }else{ img.src = './award.jpg'; } };
randomImg関数の機能は画像をランダム化することです
ランダムな画像の場合は、Math.random()乱数を使用する必要があります
canvas 2つの関数をバインドする必要があります
touchmove と touchend
var moveFunc = function(e){ var touch = e.touches[0], posX = touch.clientX - l, posY = touch.clientY - t; ctx.beginPath(); ctx.arc(posX, posY, 15, 0, Math.PI * 2, 0); ctx.fill();};
画面をスライドするときに円を描くには
destination-out
が設定されているため、スクラッチ効果が生成されますdestination-out
,所以产生了刮卡的效果
还要注意,每次触发都要ctx.beginPath();
否则ctx.fill();
会连接之前划过的圆,大面积刮涂
var endFunc = function(e){ var data = ctx.getImageData(0, 0, w, h).data, scrapeNum = 0; for(var i = 3, len = data.length; i < len; i += 4){ if(data[i] === 0){ scrapeNum++; } } if(scrapeNum > area * 0.7){ ctx.clearRect(0, 0, w, h); canvas.removeEventListener('touchmove', moveFunc, false); canvas.removeEventListener('touchend', endFunc, false); } }
手抬起时,就会触发touchend
在这个函数中,我们利用了ctx.getImageData()
获取了canvas的像素信息
关于这个函数的用法可以戳这里
当灰色图层被刮开后,后面就是canvas的背景
所以我们可以通过判断像素信息RGBA中的A是否为0来判断图层是否被刮开
scrapeNum就代表被刮开的像素点
所以通过scrapeNum > area * 0.7
各トリガーには ctx(); が必要であることにも注意してください。
それ以外の場合、ctx.fill();
は以前に描画した円を接続し、広い領域をこすり落とします
rrreee
この関数内キャンバスのピクセル情報を取得するために ctx.getImageData()
を使用しました。この関数の使用方法については、ここをクリックしてください。グレーのレイヤーが削られると、キャンバスの背景が隠れます。なので、ピクセル情報のRGBAのAが0かどうかでレイヤーがスクラッチされているかどうかが判断できます。スクラッチ範囲が全体の 70% を超える場合
グレーのレイヤー全体をクリアします
上記は、スクラッチを実装するためのモバイル端末の Touch イベントと H5-Canvas ピクセル検出の内容です。 PHP 中国語 Web サイト (www.php.cn) にアクセスしてください。