2014-05-24 24 views
1

我想在我的畫布上創建圖像失真效果,但似乎沒有任何事情發生。這裏是我的代碼:翻譯正弦波在畫布上的像素

self.drawScreen = function (abilityAnimator, elapsed) { 
    if (!self.initialized) { 
     self.initialized = true; 
     self.rawData = abilityAnimator.context.getImageData(self.targetX, self.targetY, self.width, self.height); 
     self.initialImgData = self.rawData.data; 
    } 
    abilityAnimator.drawBackground(); 
    self.rawData = abilityAnimator.context.getImageData(self.targetX, self.targetY, self.width, self.height); 
    var imgData = self.rawData.data, rootIndex, translationIndex, newX; 
    for (var y = 0; y < self.height; y++) { 
     for (var x = 0; x < self.width; x++) { 
      rootIndex = (y * self.height + x) * 4; 
      newX = Math.ceil(self.amplitude * Math.sin(self.frequency * (y + elapsed))); 
      translationIndex = (y * self.width + newX) * 4; 
      imgData[translationIndex + 0] = self.initialImgData[rootIndex + 0]; 
      imgData[translationIndex + 1] = self.initialImgData[rootIndex + 1]; 
      imgData[translationIndex + 2] = self.initialImgData[rootIndex + 2]; 
      imgData[translationIndex + 3] = self.initialImgData[rootIndex + 3]; 
     } 
    } 
    abilityAnimator.context.putImageData(self.rawData, self.targetX, self.targetY); 
}; 

abilityAnimator是我的畫布對象的包裝:

abilityAnimator.context = //canvas.context 
abilityAnimator.drawBackground = function(){ 
    this.canvas.width = this.canvas.width; 
} 

elapsed僅僅是因爲動畫開始的毫秒數(過去總是< = 2000) 我的會員變量具有以下值:

self.width = 125; 
self.height = 125; 
self.frequency = 0.5; 
self.amplitude = self.width/4; 
self.targetX = //arbitrary value within canvas 
self.targetY = //arbitrary value within canvas 

我可以很容易地將圖像翻譯到右側,因此l因爲沒有正弦功能,但是,引入這些行:

newX = Math.ceil(self.amplitude * Math.sin(self.frequency * (y + elapsed))); 
translationIndex = (y * self.width + newX) * 4; 

根本不會導致任何呈現。翻譯指標看起來並不是很奇怪,正弦函數的本質應該保證偏移不大於125/4像素。

回答

2

你使用罪惡的公式是錯誤的,頻率會很高,它會被視爲噪音。
典型公式建立一個正弦曲線是:

res = sin (2 * PI * frequency * time) ; 

其中頻率是以Hz和時間在秒。 所以JS會翻譯成:

res = Math.sin ( 2 * Math.PI * f * time_ms * 1e-3) ; 

可以很明顯的只計算一次常數因子:

self.frequency = 0.5 * ( 2 * Math.PI * 1e-3); 
// then use 
    res = Math.sin ( self.frequency * time_ms) ; 

所以你看你是1000倍太快。

第二期: 現在,你有你的時間頻率好吧,讓我們解決您的空間頻率:由y乘以時間頻率的時候,你很加入蘋果和貓。
要構建公式,請考慮在畫布高度期間跨越n * 2 * PI。
所以:

spatialFrequency = (n) * 2 * Math.PI/canvasHeight ; 

和您的公式變爲:

res = Math.sin ( self.frequency * time_ms + spatialFrequency * y) ; 

你可以用各種值播放本jsbin我做,所以你可以想像的效果:

http://jsbin.com/ludizubo/1/edit?js,output

enter image description here

+0

此工具非常有用,感謝您的參考! – jokulmorder

+0

@jokulmorder:我很高興如果這個我做的jsbin可以幫助你爲你的效果決定正確的值。如果你有一個在線版本的圖像扭曲效果,請不要猶豫,在這裏發帖! – GameAlchemist