Cara Membuat Animasi Wave dengan Javascript

Berfokus pada bidang desain serta artistik, kehadiran P5.js sebagai subsider dari Javascript selalu memberikan inspirasi tersendiri bagi para pengembang web. Seringkali, penggunaan P5.js dilibatkan dalam pemberian efek background (maupun transisi) pada suatu website. Juga, para pengembang web sering berinteraksi dengan bahasa pemrograman terkait sebagai media animasi (melalui berbagai package yang telah mendukung P5.js)

Sebagai presentasi dari fungsionalitas animasi, pada artikel kali ini, kita akan membuat animasi wave menggunakan bahasa pemrograman P5.js (subsider dari Javascript).

Langkah:

1. Persiapkan text editor (notepad, sublime text, dan sebagainya) sebagai media pengetikan syntax nantinya.

2. Buatlah file yang bernama index.html yang berisikan kode sebagai berikut:

<html>
<head>
  <title>Inwepo Wave Animation</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
</head>
<body>
  <script>
  </script>
</body>
</html>

3. Pada bagian <script>, masukkan kode berikut:

var frame;
var scaleY = 30;
var framesPerPeriod = 180;

function triPoints(points) {
  points.forEach(function(point) {
    triangle(point.x, point.y, 
             point.x + 3, point.y + 4, 
             point.x - 3, point.y + 4);
  });
}

function rectsPoints(points, width, baseline, offset, alpha) {
  push();
  strokeWeight(0);
  fill(4,24,64, alpha);
  points.forEach(function(point) {
    var height = baseline - point.y;
    var y = point.y + offset.y + Math.round(height / 2);
    rect(point.x + offset.x, y, width, height);
  });
  pop();
} 

function curvePoints(points) {
  beginShape();
  points.forEach(function(p) {
    curveVertex(p.x, p.y);
  });
  endShape();
  
}

function subdivisionsForPoints(points, rectCount) {
  var maxY = points[1].y;
  var minX = points[1].x;
  var maxX = points[points.length-2].x;
  var rectWidth = Math.ceil((maxX - minX) / (2*rectCount + 2));
  var ii = 1;
  var results = [];
  for (var x = minX; x < maxX; x += 2 *rectWidth) {
    var p0 = points[ii - 1];
    var p1 = points[ii];
    var p2 = points[ii+1];
    var p3 = points[ii+2];
    while(p2.x < x && ii < points.length - 3) {
      ii++;
      p0 = points[ii-1];
      p1 = points[ii];
      p2 = points[ii+1];
      p3 = points[ii+2];
    }
	
    var ratio = (x - p1.x + rectWidth/2) / (p2.x - p1.x);
    var y = curvePoint(p0.y, p1.y, p2.y, p3.y, ratio);
    results.push({x: x, y: y});
  }
  return results;
}

function points(time, width) {
  var scaleX = width / 7;
  var pt = function(x, y) {
    return {x: x*scaleX, y: y*scaleY};
  }
  
  return [
    pt(-1, 10),
    pt(0, 10),
    pt(2, 5 + Math.cos(time/framesPerPeriod *2*Math.PI)*1.5),
    pt(3.5, 7.5 + Math.sin(time/framesPerPeriod *2*Math.PI)*1.2),
    pt(5, 5 + Math.sin(time/framesPerPeriod *2*Math.PI)*1.5),
    pt(7, 10),
    pt(8, 10),
  ];
}

function drawRows(pointLists, rectWidth, baseline, initialOffset, rowHeight, rowCount, frame) {
  for (var ii = 0; ii < rowCount; ii++) {
    var points = pointLists[ii % pointLists.length];
    var x = (ii % 2 === 0) ? 0 : rectWidth;
    var alpha = Math.sin((frame + ii*3*rowCount)/framesPerPeriod *2*Math.PI)*90 + 165;
  rectsPoints(points, rectWidth, baseline, {x: x, y: initialOffset + ii*rowHeight}, alpha);
  }
}

function header(){
	fill(color("#fff"));
    rect(0,0,width,100);
	fill(24,46,97);
	textFont('Segoe UI');
	textSize(50);
	textAlign(CENTER);
	text("Inwepo Wave Animation", width/2, 60);
}

function draw() {
  clear();
  background(24,46,97);
  var subdivisionCount = winMouseX === 0 ? 24 : (winMouseX / windowWidth) * (128 - 8) + 8;
  
  var pLists = [
    points(frame, windowWidth),
    points(frame + .25*framesPerPeriod, windowWidth),
    points(frame + .5*framesPerPeriod, windowWidth),
    points(frame + .75*framesPerPeriod, windowWidth),
  ];
  var subPointLists = pLists.map(function(points) {
    return subdivisionsForPoints(points, windowWidth/subdivisionCount);
  });
  
  var rectWidth = Math.ceil((subPointLists[0][0].x - subPointLists[0][1].x)/2);
  var rowHeight = 3*scaleY;
  var rowCount = Math.ceil(windowHeight / rowHeight)+3;
  var baseline = pLists[0][0].y;
  
  drawRows(subPointLists, rectWidth, baseline, -baseline, rowHeight, rowCount, frame);
  frame++;
  header();
}

function setup() {
  frame = 0;
  createCanvas(windowWidth,windowHeight);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

Nantinya, bagian <script> akan memiliki struktur kode sebagai berikut:

<script>
	var frame;
	var scaleY = 30;
	var framesPerPeriod = 180;

	function triPoints(points) {
	  points.forEach(function(point) {
		triangle(point.x, point.y, 
				 point.x + 3, point.y + 4, 
				 point.x - 3, point.y + 4);
	  });
	}

	function rectsPoints(points, width, baseline, offset, alpha) {
	  push();
	  strokeWeight(0);
	  fill(4,24,64, alpha);
	  points.forEach(function(point) {
		var height = baseline - point.y;
		var y = point.y + offset.y + Math.round(height / 2);
		rect(point.x + offset.x, y, width, height);
	  });
	  pop();
	} 

	function curvePoints(points) {
	  beginShape();
	  points.forEach(function(p) {
		curveVertex(p.x, p.y);
	  });
	  endShape();
	  
	}

	function subdivisionsForPoints(points, rectCount) {
	  var maxY = points[1].y;
	  var minX = points[1].x;
	  var maxX = points[points.length-2].x;
	  var rectWidth = Math.ceil((maxX - minX) / (2*rectCount + 2));
	  var ii = 1;
	  var results = [];
	  for (var x = minX; x < maxX; x += 2 *rectWidth) {
		var p0 = points[ii - 1];
		var p1 = points[ii];
		var p2 = points[ii+1];
		var p3 = points[ii+2];
		while(p2.x < x && ii < points.length - 3) {
		  ii++;
		  p0 = points[ii-1];
		  p1 = points[ii];
		  p2 = points[ii+1];
		  p3 = points[ii+2];
		}
		
		var ratio = (x - p1.x + rectWidth/2) / (p2.x - p1.x);
		var y = curvePoint(p0.y, p1.y, p2.y, p3.y, ratio);
		results.push({x: x, y: y});
	  }
	  return results;
	}

	function points(time, width) {
	  var scaleX = width / 7;
	  var pt = function(x, y) {
		return {x: x*scaleX, y: y*scaleY};
	  }
	  
	  return [
		pt(-1, 10),
		pt(0, 10),
		pt(2, 5 + Math.cos(time/framesPerPeriod *2*Math.PI)*1.5),
		pt(3.5, 7.5 + Math.sin(time/framesPerPeriod *2*Math.PI)*1.2),
		pt(5, 5 + Math.sin(time/framesPerPeriod *2*Math.PI)*1.5),
		pt(7, 10),
		pt(8, 10),
	  ];
	}

	function drawRows(pointLists, rectWidth, baseline, initialOffset, rowHeight, rowCount, frame) {
	  for (var ii = 0; ii < rowCount; ii++) {
		var points = pointLists[ii % pointLists.length];
		var x = (ii % 2 === 0) ? 0 : rectWidth;
		var alpha = Math.sin((frame + ii*3*rowCount)/framesPerPeriod *2*Math.PI)*90 + 165;
	  rectsPoints(points, rectWidth, baseline, {x: x, y: initialOffset + ii*rowHeight}, alpha);
	  }
	}

	function header(){
		fill(color("#fff"));
		rect(0,0,width,100);
		fill(24,46,97);
		textFont('Segoe UI');
		textSize(50);
		textAlign(CENTER);
		text("Inwepo Wave Animation", width/2, 60);
	}

	function draw() {
	  clear();
	  background(24,46,97);
	  var subdivisionCount = winMouseX === 0 ? 24 : (winMouseX / windowWidth) * (128 - 8) + 8;
	  
	  var pLists = [
		points(frame, windowWidth),
		points(frame + .25*framesPerPeriod, windowWidth),
		points(frame + .5*framesPerPeriod, windowWidth),
		points(frame + .75*framesPerPeriod, windowWidth),
	  ];
	  var subPointLists = pLists.map(function(points) {
		return subdivisionsForPoints(points, windowWidth/subdivisionCount);
	  });
	  
	  var rectWidth = Math.ceil((subPointLists[0][0].x - subPointLists[0][1].x)/2);
	  var rowHeight = 3*scaleY;
	  var rowCount = Math.ceil(windowHeight / rowHeight)+3;
	  var baseline = pLists[0][0].y;
	  
	  drawRows(subPointLists, rectWidth, baseline, -baseline, rowHeight, rowCount, frame);
	  frame++;
	  header();
	}

	function setup() {
	  frame = 0;
	  createCanvas(windowWidth,windowHeight);
	}

	function windowResized() {
	  resizeCanvas(windowWidth, windowHeight);
	}
</script>

4. Save file yang telah dimodifikasi sebelumnya. Lalu, buka file index.html melalui browser kamu. Jika berhasil, nantinya halaman website akan menampilkan konten teks menyertakan animasi wave dengan motion control (menggunakan mouse) sesuai dengan syntax yang telah kita masukkan. Sesuaikan penggunaan animasi wave dengan website yang telah kamu buat.

Demikian tutorial cara membuat animasi wave dengan Javascript. Semoga bermanfaat.

Komentar

Leave a Reply

Your email address will not be published. Required fields are marked *

Inwepo adalah media platform yang membantu setiap orang untuk belajar dan berbagi tutorial, tips dan trik cara penyelesaian suatu masalah di kehidupan sehari-hari dalam bentuk teks, gambar. dan video.

Dengan bergabung bersama kami dan membuat 1 tutorial terbaik yang kamu miliki dapat membantu jutaan orang di Indonesia untuk mendapatkan solusinya. Ayo berbagi tutorial terbaikmu.

Ikuti Kami di Sosmed

Copyright © 2020 Inwepo - All Rights Reserved.

To Top