JSFiddle - React, Tailwind, and code Playground
HTML
<input id='iw' value='500'><input id='ih' value='300'> - Ширина/Высота<br>
<input id='ix1' value='150'><input id='iy1' value='150'> - Точка 1 (x,y)<br>
<input id='ix2' value='250'><input id='iy2' value='150'> - Точка 2 (x,y)<br>
<input id='il1' value='10'><input id='if1' value='0'> - Длина волны от точки 1 и фаза<br>
<input id='il2' value='10'><input id='if2' value='0'> - Длина волны от точки 2 и фаза<br>
<input type='button' id='b1' value='Обновить'><input type='button' id='b2' value='Анимация'><br>
<canvas id='cv'></canvas>
JavaScript
var ct=cv.getContext('2d');
var q=1, b=0, t=0, img, x1, y1, x2, y2, l1, l2, f1, f2, w;
init();
interf();
cv.onclick=function() {
if (q==0) q=1;
else q=0;
if (b==0) interf();
}
b1.onclick=function() {
init();
if (b==0) interf();
}
b2.onclick=function() {
if (b==0) {
b=1;
b2.value='Стоп';
go=setInterval(interf, 17);
}
else {
b=0;
b2.value='Анимация';
clearInterval(go);
}
}
function init() {
cv.width=+iw.value;
cv.height=+ih.value;
img=ct.getImageData(0, 0, cv.width, cv.height);
x1=+ix1.value;
y1=+iy1.value;
x2=+ix2.value;
y2=+iy2.value;
l1=+il1.value;
l2=+il2.value;
f1=+if1.value;
f2=+if2.value;
w=cv.width;
}
function interf() {
for (var i=0, len=img.data.length; i<len; i+=4) {
var y=(i/4/w|0)+1;
var x=i/4+1-(y-1)*w;
var diag1=Math.sqrt(Math.pow(x1-x, 2)+Math.pow(y1-y, 2));
var diag2=Math.sqrt(Math.pow(x2-x, 2)+Math.pow(y2-y, 2));
var a1=Math.sin(2*Math.PI*((diag1 - t)/l1+f1/360));
var a2=Math.sin(2*Math.PI*((diag2 - t)/l2+f2/360));
if (diag1>=1 && q==1) a1/=Math.sqrt(diag1);
if (diag2>=1 && q==1) a2/=Math.sqrt(diag2);
var col=(255*(a1+a2+2)/4)|0;
img.data[i]=col;
img.data[i+1]=col;
img.data[i+2]=col;
img.data[i+3]=255;
}
if (b==1) t+=0.1;
ct.putImageData(img, 0, 0);
}