简体   繁体   English

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

[英]Translating pixels in canvas on sine wave

I am trying to create an image distortion effect on my canvas, but nothing appears to be happening. 我正在尝试在画布上创建图像失真效果,但是似乎没有任何反应。 Here is my code: 这是我的代码:

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 is a wrapper for my canvas object: abilityAnimator是我的画布对象的包装器:

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

elapsed is simply the number of milliseconds since the animation began (elapsed is always <= 2000) My member variables have the following values: 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

I can translate the image to the right very easily so long as there is no sine function, however, introducing these lines: 只要没有正弦函数,我就可以很容易地将图像右移,但是请引入以下几行:

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

Causes nothing to render at all. 完全不进行渲染。 The translation indexes don't appear to be very strange, and the nature of the sinusoidal function should guarantee that the offset is no greater than 125 / 4 pixels. 平移索引似乎并不奇怪,正弦函数的性质应确保偏移量不大于125/4像素。

Your formula using sin is wrong, the frequency will be so high it will be seen as noise. 您使用sin的公式是错误的,频率会很高,会被视为噪声。
The typical formula to build a sinusoid is : 建立正弦曲线的典型公式为:

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

where frequency is in Hz and time in s. 频率以Hz为单位,时间以s为单位。 So in js that would translate to : 所以在js中,它会转换为:

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

you can obviously compute just once the constant factor : 您显然可以只计算一次常数因子:

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

So you see you were 1000 times too fast. 因此,您看到自己快了1000倍。

Second issue : Now that you have your time frequency ok, let's fix your spatial frequency : when multiplying time frequency by y , you're quite adding apples and cats. 第二个问题:现在您可以确定时间频率了,让我们来确定您的空间频率:当将时间频率乘以y ,您就在添加苹果和猫。
To build the formula, think that you want to cross n time 2*PI during the height of the canvas. 要构建公式,请考虑您要在画布高度上穿越n时间2 * PI。
So : 因此:

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

and your formula becomes : 并且您的公式变为:

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

You can play with various values with this jsbin i made so you can visualize the effect : 您可以使用我制作的这个jsbin来玩各种值,以便可视化效果:

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

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM