Brzdąkałeś kiedyś na linijce opartej o krawędź biurka? Dziś będziesz mieć okazję do efektów audio dodać efekty wideo oparte na podobnej zasadzie. Też będziemy brzdąkać na czymś elastycznym, podobnym do linijki. Być może obiło Ci się o uszy hasło "krzywa Béziera". Nie będziemy wnikać w jej podstawy matematyczne, lecz wykorzystamy wprost jej właściwości. Ta krzywa (inaczej spline) przypomina właśnie naszą linijkę, albo jeszcze lepiej listewkę ratanu przeplataną przez gałązki wikliny. Końcówki listewki mocujemy na stałe, natomiast gałązki wikliny powodują odkształcenie elastycznej listewki (w krzywej te wszystkie punkty nazywa się punktami kontrolnymi).
Przygotuj materiały!
Będzie nam potrzebna listewka ratanowa i dwie gałązki gałązki wikliny. Będziemy się bawić krzywą trzeciego stopnia (4 punkty kontrolne minus 1), zwaną inaczej krzywą sześcienną. W JavaScript tą listewkę możemy wyginać przy pomocy metody bezierCurveTo. Podajemy jej punkty kontrolne 2-4, a pierwszy punkt ustalamy przy pomocy metody moveTo.
Wykreślmy taką przykładową krzywą.
<canvas width="200" height="200"></canvas>
+
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
/* krzywa od punktu 10,100 do punktu 190,100
przez punkty 70,80 oraz 130,120
*/
ctx.moveTo(10, 100);
ctx.bezierCurveTo(70, 80, 130, 120, 190, 100);
ctx.stroke();
/* tu kreślimy tylko punkty kontrolne */
ctx.beginPath();
ctx.rect(10 - 2, 100 - 2, 4, 4);
ctx.fillStyle = "blue";
ctx.fill();
ctx.beginPath();
ctx.rect(70 - 2, 80 - 2, 4, 4);
ctx.fillStyle = "red";
ctx.fill();
ctx.beginPath();
ctx.rect(130 - 2, 120 - 2, 4, 4);
ctx.fillStyle = "green";
ctx.fill();
ctx.beginPath();
ctx.rect(190 - 2, 100 - 2, 4, 4);
ctx.fillStyle = "yellow";
ctx.fill();
ctx.beginPath();
ctx.moveTo(10, 100);
ctx.lineTo(70, 80);
ctx.lineTo(130, 120);
ctx.lineTo(190, 100);
ctx.strokeStyle = '#dddddd';
ctx.stroke();
Tak się wygnie:
Pierwszy i ostatni punkty kontrolny zawsze stanowią punkty mocowania krzywej, natomiast pozostałe powodują wygięcie krzywej, ale nie leżą na niej. Zmieniając punkty kontrolne możemy powodować, że listewka będzie drgać - trząść się jak listewka osikowa. Nie bylibyśmy sobą, gdybyśmy tego nie wykorzytali, prawda?
Nie trzęś portkami, trzęś listewkami!
Aby nasza listewka zaczęła drgać wystarczy dodać do jej punktów kontrolnych (wewnętrznych i/lub krańcowych) jakieś wartości losowe i kreślić ją na nowo co określony interwał czasowy. Zróbmy tak.
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
setInterval(function() {
/* tym razem współrzędne Y punktów są tej samej wartości
będziemy je zmieniać dodając wartości losowe
*/
var x1 = 10;
var y1 = 100;
var x2 = 70;
var y2 = 100;
var x3 = 130;
var y3 = 100;
var x4 = 190;
var y4 = 100;
x1 += Math.random() * 5;
y1 += Math.random() * 5;
x2 += Math.random() * 5;
y2 += Math.random() * 5;
x3 += Math.random() * 5;
y3 += Math.random() * 5;
x4 += Math.random() * 5;
y4 += Math.random() * 5;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.bezierCurveTo(x2, y2, x3, y3, x4, y4);
ctx.strokeStyle = 'black';
ctx.stroke();
ctx.beginPath();
ctx.rect(x1 - 2, y1 - 2, 4, 4);
ctx.fillStyle = "blue";
ctx.fill();
ctx.beginPath();
ctx.rect(x2 - 2, y2 - 2, 4, 4);
ctx.fillStyle = "red";
ctx.fill();
ctx.beginPath();
ctx.rect(x3 - 2, y3 - 2, 4, 4);
ctx.fillStyle = "green";
ctx.fill();
ctx.beginPath();
ctx.rect(x4 - 2, y4 - 2, 4, 4);
ctx.fillStyle = "yellow";
ctx.fill();
}, 100);
I nasza strachliwa listewka:
Czy ta krzywa zaczyna Ci przypominać nakreśloną kreskę kreślarza z kreskówki? A gdyby dodać tych kresek trochę więcej i utworzyć z nich jakiś rysunek?
Proszę bardzo!
Pozostawiam Cię trzęsącego się z emocji. Kolejne emocje w następnym wpisie, na który Cię oczywiście zapraszam.
Przydatne linki:
Metoda moveTo w JavaScript
Metoda bezierCurveTo w JavaScript
Krzywa Béziera