在正弦波上平移画布中的像素

时间:2014-05-24 16:14:54

标签: javascript html5 canvas

我正在尝试在画布上创建图像扭曲效果,但似乎没有发生任何事情。这是我的代码:

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是我的canvas对象的包装器:

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

elapsed只是动画开始后的毫秒数(经过的时间总是&lt; = 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

只要没有正弦函数,我就可以很容易地将图像转换到右边,但是,引入这些行:

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

根本不呈现任何内容。翻译索引似乎不太奇怪,正弦函数的性质应该保证偏移不大于125/4像素。

1 个答案:

答案 0 :(得分:2)

使用罪的公式是错误的,频率会很高,会被视为噪音 构建正弦曲线的典型公式是:

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

其中频率以Hz为单位,时间以s为单位。 所以在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时,你就可以完全添加苹果和猫了。
要构建公式,请认为您希望在画布高度期间跨越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