HTML5+JS
효과는 HTML5 캔버스 요소에서 바닐라 JavaScript를 사용하여 만들어집니다. 이 섹션에서는 도형 그리기, 반복으로 그리기, 모션 추가의 기초를 다룹니다.
도형 그리기
섹션 제목: “도형 그리기”이 튜토리얼에서는 일반적인 Lightscript 템플릿을 사용합니다:
<head> <meta description="Template"/> <meta publisher="WhirlwindFX" /></head>
<body style="margin: 0; padding: 0;"> <canvas id="exCanvas" width="320" height="200"></canvas></body>
<script> // Get the canvas element from the DOM var c = document.getElementById("exCanvas"); var ctx = c.getContext("2d");
var width = 320; var height = 200; var hue = 0;
function update() { // Code goes here window.requestAnimationFrame(update); }
window.requestAnimationFrame(update);</script>선을 하나 그리든 여러 개 그리든 과정은 동일합니다.
- **ctx.beginPath()**로 도형을 시작합니다.
- **ctx.moveTo(x, y)**로 첫 번째 점을 설정합니다.
- **ctx.lineTo(x, y)**로 다음 점을 설정하고 첫 번째 점으로 이어지는 선을 만듭니다. 더 큰 도형을 그리려면 lineTo를 여러 번 사용하십시오.
- ctx.strokeStyle 및/또는 ctx.fillStyle을 설정합니다(도형이 닫혀 있는 경우).
- **ctx.stroke()**로 선을 그리고, **ctx.fill()**로 닫힌 도형을 채웁니다. 이 명령이 실행되기 전까지는 모든 것이 가상 상태임을 주의하십시오.
선을 사용하는 세 가지 예시입니다:
function update() { // One Line ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(30, 170); ctx.strokeStyle = "blue"; ctx.stroke();
// L ctx.beginPath(); ctx.moveTo(80, 30); ctx.lineTo(80, 100); ctx.lineTo(120, 100); ctx.strokeStyle = "blue"; ctx.stroke();
// Filled Triangle ctx.beginPath(); ctx.moveTo(130, 30); ctx.lineTo(130, 100); ctx.lineTo(170, 100); ctx.lineTo(130, 30); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update);}
여기서 그리기 순서에 주의하십시오: 채워진 삼각형이 마지막에 그려지므로 같은 위치에 있었다면 다른 두 도형을 덮었을 것입니다. 또한 삼각형의 획은 채우기 후에 그려집니다. 이 단계를 반대로 하면 획의 안쪽 절반이 빨간색 채우기로 덮힐 것입니다.
직사각형
섹션 제목: “직사각형”직사각형은 단순하고 유용하며, 특히 RGB 키보드의 평균 해상도에 적합합니다. 선 그리기와 과정이 유사합니다. moveTo와 lineTo 명령을 **rect(x, y, width, height)**로 대체하기만 하면 됩니다.
function update() { // Basic Square ctx.beginPath(); ctx.rect(30, 30, 75, 75); ctx.strokeStyle = "blue"; ctx.stroke();
// Filled Rectangle ctx.beginPath(); ctx.rect(125, 30, 125, 100); ctx.fillStyle = "red"; ctx.strokeStyle = "blue"; ctx.fill(); ctx.stroke();
window.requestAnimationFrame(update); }
호는 중심점을 기준으로 외부 점을 회전시켜 그리며, 완전한 원을 만드는 데 사용할 수 있습니다. 호 명령은 **ctx.arc(x, y, 반지름, 시작 각도, 끝 각도)**이며, 두 각도는 모두 라디안으로 지정합니다. 직사각형과 달리 호는 도형의 원점 (x, y)이 호의 중심에 위치합니다.
function update() { // Half-circle ctx.beginPath(); ctx.arc(70, 100, 30, 0, Math.PI); ctx.strokeStyle = "blue"; ctx.stroke();
// 3/4 circle ctx.beginPath(); ctx.arc(140, 100, 30, 0, Math.PI * (3/2)); ctx.strokeStyle = "blue"; ctx.stroke();
// Full circle ctx.beginPath(); ctx.arc(210, 100, 30, 0, Math.PI * 2); ctx.strokeStyle = "blue"; ctx.stroke(); ctx.fillStyle = "red"; ctx.fill();
window.requestAnimationFrame(update); }
보시다시피 호는 기본적으로 시계 방향으로 그려집니다. 시작 각도보다 작은 끝 각도를 사용하거나 ctx.arc() 메서드의 마지막 인수로 “true”를 추가하면 반시계 방향으로 변경할 수 있습니다.
반복으로 그리기
섹션 제목: “반복으로 그리기”도형 세 개를 직접 그리는 데 쉽게 스무 줄의 코드가 필요할 수 있으므로, 백 개의 도형을 그려야 한다면 더 효율적인 방법이 필요합니다. JavaScript의 루프는 작업을 반복하는 간단한 방법이며 그리기에도 적용할 수 있습니다.
for 루프를 사용하여 체크무늬 정사각형 행을 그리는 예시입니다:
function update() {
for(let i = 0; i < 8; i++){
// 1. Create rectangle path and draw the stroke for each. ctx.beginPath(); ctx.rect(i * 20, 20, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 2. If 'i' is even, the fillStyle is black. Otherwise it's white. if(i % 2 == 0){ ctx.fillStyle = "black"; } else { ctx.fillStyle = "white"; } // 3. Fill the shape after setting the fillStyle. ctx.fill(); }
window.requestAnimationFrame(update); }
체크무늬 격자를 그리는 while 루프 예시입니다. 템플릿 리터럴을 사용하여 각 반복에서 검정 정사각형의 밝기와 흰색 정사각형의 색조를 약간씩 변경합니다.
function update() {
var i = 0;
while(i < 16){
// 1. X and Y calculations with 'row' and 'column' var iRow = Math.floor(i / 4); var iCol = i % 4; var ix = iCol * 20; var iy = iRow * 20;
// 2. Path and stroke ctx.beginPath(); ctx.rect(ix, iy, 20, 20); ctx.strokeStyle = "black"; ctx.stroke();
// 3. Fill based on row/column parity if(iRow % 2 == 0){ if(i % 2 == 0){ ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } else { ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } } else { if(i % 2 == 0){ ctx.fillStyle = `hsl(${10 * i}, 100%, 50%)`; } else { ctx.fillStyle = `hsl(1, 0%, ${5 * i}%)` } }
ctx.fill(); i++; }
window.requestAnimationFrame(update); }
모션 추가
섹션 제목: “모션 추가”캔버스 애니메이션은 여러분의 상상력과 수학 지식에 의해서만 제한됩니다. 삼각법이나 기하학이 불안하다면 실력을 한 단계 높이기 위해 가벼운 자료를 찾아보는 것을 권장합니다. 다음 몇 가지 예시에서 정적인 원에 단순한 진동 모션을 사용하여 가능한 모든 변수를 연결합니다.
진동(규칙적인 앞뒤 운동)의 황금 표준은 타이머의 sin() 또는 **코사인()**을 취하는 것입니다. 두 연산 모두 ANY 값이 전달되더라도 -1에서 1 사이의 값을 반환합니다. 두 연산의 유일한 차이점은 약간 동기화되어 있지 않다는 것입니다. cos가 0일 때 sin은 -1 또는 1이고, 반대로도 마찬가지입니다. 이를 이 애니메이션에서 활용할 수 있습니다:
function update() {
// Find current time in milliseconds, then divide to slow down the animation speed let time = Date.now() / 100;
// Draw a background so the old shapes don't stick around ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath();
//USE ONE EXAMPLE AT A TIME // 1st example - side to side, y is constant ctx.arc(15 * Math.cos(time) + 160, 100, 30, 0, Math.PI * 2); // 2nd example - up and down, x is constant ctx.arc(160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2); // 3rd example - circle, x and y are variable ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30, 0, Math.PI * 2);
ctx.fillStyle = "black"; ctx.fill();
window.requestAnimationFrame(update); }좌우 이동
섹션 제목: “좌우 이동”
상하 이동
섹션 제목: “상하 이동”
원형 이동
섹션 제목: “원형 이동”
이제 시간에 따라 변경할 수 있는 몇 가지 속성이 더 남았습니다: 원 반지름, 채우기, 획. 도형을 단순하게 유지하기 위해 호 각도는 그대로 두겠습니다. 나머지는 꽤 화려해질 것입니다.
function update() {
let time = Date.now() / 100;
ctx.fillStyle = "white"; ctx.fillRect(0, 0, 320,200);
ctx.beginPath(); ctx.arc(15 * Math.cos(time) + 160, 15 * Math.sin(time) + 100, 30 + 15 * Math.sin(time), 0, Math.PI * 2);
ctx.fillStyle = `hsl(${180 + 180 * Math.cos(time)}, 100%, 50%)`; ctx.fill();
ctx.strokeStyle = `hsl(${180 + 180 * Math.sin(time)}, 100%, 50%)`; ctx.stroke();
window.requestAnimationFrame(update); }
지금까지 만든 모든 도형의 모든 속성을 시간에 따라 변경할 수 있으며, 제가 만드는 모든 애니메이션은 위의 기술을 조합한 것입니다. 재사용 가능하고 효율적인 애니메이션 제작에 대한 자세한 내용은 콜백 페이지를 확인하십시오!