2013-10-02 3 views
14

私はキャンバス要素を少し試していて、効果を引き出す方法が不思議でした。キャンバスとJavaScriptで画像をピクセル化する方法

私はチュートリアルやデモのコレクションから探しているものを幾分得ていますが、残りの部分を手助けする必要があります。私が探しているのは、画像をmouseoverにピクセル化してから、mouseoutに再フォーカス/非ピクセル化することです。メインカルーセルの下にあるブロックをマウスで覆うと、http://www.cropp.com/の効果の良い例が見られます。

ここはlink to a fiddleです。あなたがクロスドメインイメージ(womp womp)を使用することはできないので、このフィーリングは機能しませんが、これまでのところ私のコードを見ることができます。私のキャンバスオブジェクトにマウスをかけるとイメージをピクセル化することができますが、それは私が得ようとしているものに逆らっています。どんな助けやアドバイスも大歓迎です。

var pixelation = 40, 
    fps = 120, 
    timeInterval = 1000/fps, 
    canvas = document.getElementById('photo'), 
    context = canvas.getContext('2d'), 
    imgObj = new Image(); 

imgObj.src = 'images/me.jpg'; 
imgObj.onload = function() {  
    context.drawImage(imgObj, 0, 0); 
}; 

canvas.addEventListener('mouseover', function() { 
    var interval = setInterval(function() { 
     context.drawImage(imgObj, 0, 0); 

     if (pixelation < 1) { 
      clearInterval(interval); 
      pixelation = 40; 
     } else { 
      pixelate(context, canvas.width, canvas.height, 0, 0); 
     } 
    }, timeInterval); 
}); 

function pixelate(context, srcWidth, srcHeight, xPos, yPos) { 

    var sourceX = xPos, 
     sourceY = yPos, 
     imageData = context.getImageData(sourceX, sourceY, srcWidth, srcHeight), 
     data = imageData.data; 

    for (var y = 0; y < srcHeight; y += pixelation) { 
     for (var x = 0; x < srcWidth; x += pixelation) { 

      var red = data[((srcWidth * y) + x) * 4], 
       green = data[((srcWidth * y) + x) * 4 + 1], 
       blue = data[((srcWidth * y) + x) * 4 + 2]; 

      for (var n = 0; n < pixelation; n++) { 
       for (var m = 0; m < pixelation; m++) { 
        if (x + m < srcWidth) { 
         data[((srcWidth * (y + n)) + (x + m)) * 4] = red; 
         data[((srcWidth * (y + n)) + (x + m)) * 4 + 1] = green; 
         data[((srcWidth * (y + n)) + (x + m)) * 4 + 2] = blue; 
        } 
       } 
      } 
     } 
    } 

    // overwrite original image 
    context.putImageData(imageData, xPos, yPos); 
    pixelation -= 1; 
} 
+3

データURLを使用してフィーリングを実際のイメージに更新しました:http://jsfiddle.net/xDt7U/1/ – Chad

答えて

29

ピクセル化効果を作成するためにピクセルバッファを繰り返す必要はありません。

画像のスムージングをオフにして、画像の小さなバージョンをキャンバスに拡大するだけです。これはまた、任意のイメージをソースとして使用できることを意味します(CORS単位)。

例:デモで

Fiddle demo

// get a block size (see demo for this approach) 
var size = blocks.value/100, 
    w = canvas.width * size, 
    h = canvas.height * size; 

// draw the original image at a fraction of the final size 
ctx.drawImage(img, 0, 0, w, h); 

// turn off image aliasing 
ctx.msImageSmoothingEnabled = false; 
ctx.mozImageSmoothingEnabled = false; 
ctx.webkitImageSmoothingEnabled = false; 
ctx.imageSmoothingEnabled = false; 

// enlarge the minimized image to full size  
ctx.drawImage(canvas, 0, 0, w, h, 0, 0, canvas.width, canvas.height); 

あなたはブラウザがの世話をするなどの性能は、ピクセル反復方式に比べて非常に良好であることを確認するには、この効果をアニメーション化することができます内部的にコンパイルされたコードの "ピクセル化"

+0

ワウは素晴らしいと私は行っていたよりはるかに少ないコード。おそらくコードを少し説明してもらえますか?私はpixelateメソッドが何をしているのか理解していますが、toggleAnimの動作方法とrequestAnimationFrameについて興味があります。どのようにして特定のポイント(ピクセル化された)にアニメートしてから停止することができますか?またはその逆? – brandongray

+0

@brandongray toggleAnimは、パフォーマンスの印象を得るためにピクセル化をアニメーション化するデモの一部に過ぎません。私はインラインコメントでデモを更新しました。 requestAnimationFrameは低レベルのアニメーションメソッドで、アニメーションを同期させて更新を監視し、スムーズでパフォーマンスの高いものにします。 setTimout/setIntervalよりも優れています。 – K3N

+0

@ ken-abdias-softwareコメントに感謝します。別の分があり、喜んで助けてくれるなら、[このフィドル](http://jsfiddle.net/Ra9KQ/)を見てください。マウスオーバー/アウトで作業していますが、汚れているようです。たとえば、マウスを素早くマウスオーバーしてから外に出すと、スムーズに見えません。マウスオーバー機能は、その時点で引き続き実行されます。どのように私はそれをスムーズに移行することができるかに関する任意の提案?たとえば、マウスを素早くホバーしてからマウスを離すと、ホバー効果が得られたどの点からでも遷移します。うまくいけばそれはある意味があります。 – brandongray

2

たとえば、pixelateまたはclose-pixelateのように、同じ効果を発揮するいくつかのJavaScriptライブラリがあります。

関連する問題