본문 바로가기

인지심리이론/실험 설계

[HTML5로 실험 자극 만들기] 원운동하는 점 만들기


글: 인지심리 매니아


필자는 실험 자극을 만들 때 주로 Matlab을 사용해왔다. 하지만 HTML5의 도입으로 인해 이제는 웹에서도 실험 자극을 쉽게 구현할 수 있게 되었다.  그래서 HTML5로 간단한 자극을 만드는 법을 소개하고자 한다. 


오늘은 원운동을 하는 작은 점을 만들고자 한다(필자가 실제로 실험에 사용했던 자극이다).




완성된 자극(IE8 이하 버젼에서는 예제가 보이지 않을 수 있습니다)



소스 코드

<!doctype html>

<html>

  <head>

    <meta charset="UTF-8" />

    <title>Canvas Test</title>

  </head>

<body>

  <section>


    <div>

        <canvas id="canvas" width="800" height="600">

         This text is displayed if your browser 

         does not support HTML5 Canvas.

        </canvas>

    </div>


<script type="text/javascript">

var canvas;  

var ctx;

var x = 100;

var y = 200;

var WIDTH = 400;

var HEIGHT = 400; 

var r=1;                               // 원운동 궤적의 반지름

var i=Math.PI/180;              // (라디안으로 변환한) 1도


function init() {

  canvas = document.getElementById("canvas");

  ctx = canvas.getContext("2d");

  return setInterval(draw, 20);

}



function draw() {

  clear();

  ctx.fillStyle = "#444444";

  circle(x, y, 10);


  x -= r*Math.cos(i);

  y -= r*Math.sin(i);

  i += Math.PI/180;

}


function clear() {

  ctx.clearRect(0, 0, WIDTH, HEIGHT);

}


function circle(x,y,r) {

  ctx.beginPath();

  ctx.arc(x, y, r, 0, Math.PI*2, true);

  ctx.fill();

}


init();


</script>

  </section>

</body>

</html>



이 코드는 Unknown Kadath에 소개된 코드를 필자가 수정한 것이다. 원래는 무선적으로 움직이는 점을 구현하고 있지만, 위 코드에선 점이 원운동을 하도록 수정되었다. 



이 코드의 개요는 다음과 같다.


먼저 init 함수가 실행되면 이 함수가 다시 draw 함수를 호출한다. 호출된 draw 함수는 이전 화면을 지운 다음 새 화면 위에 점을 그린다. Init 함수가 10밀리세컨드 단위로 draw 함수를 반복해서 호출하고, draw 함수는 매번 다른 위치에 점을 그리기 때문에 마치 점이 움직이는는 것처럼 보이게 된다. 




캔버스 지정하기

<canvas id="canvas" width="800" height="600">

This text is displayed if your browser does not support HTML5 Canvas.

</canvas>

먼저 도형을 그릴 캔버스를 지정한다. width는 넓이, height는 높이를 말한다.



초기 변수 지정

var canvas;  

var ctx;

var x = 100;

var y = 200;

var WIDTH = 400;

var HEIGHT = 400; 

var r=1;                               // 원운동 궤적의 반지름

var i=Math.PI/180;              // (라디안으로 변환한) 1도

x,y: 좌표를 의미한다

WIDTH와 HEIGHT: 캔버스의 크기를 의미한다

r: 원운동 궤적의 반지름을 의미한다.

i: 1도를 의미한다



init 함수

function init() {

  canvas = document.getElementById("canvas");

  ctx = canvas.getContext("2d");

  return setInterval(draw, 10);

}

Init 함수는 먼저 “canvas”의 element를 가져온다. 

그 다음 컨텍스트를 정의한다. 모든 캔버스는 컨텍스트를 가지고 있다. 우리가 그릴 그림이나 애니메이션은 모두 컨텍스트 안에서 표현된다. 여기서는 2d context를 선택했다. 

setInterval 함수는 draw 함수를 10 밀리세컨드 간격으로 반복 실행시킨다. 



draw 함수

function draw() {

  clear();

ctx.fillStyle = "#444444";

  circle(x, y, 10);


  i += Math.PI/90;

  x -= r*Math.cos(i);

  y -= r*Math.sin(i);

 

}


Draw 함수는 먼저 Clear 함수를 호출해서 이전 화면(점)을 지운다. 

function clear() {

  ctx.clearRect(0, 0, WIDTH, HEIGHT);

}


그 다음, 점의 색상을 #444444로 지정해 준다. 

그 다음, circle 함수로 작은 점을 그린다. x,y는 원의 좌표, 10은 반지름을 의미한다.

function circle(x,y,r) {

  ctx.beginPath();

  ctx.arc(x, y, r, 0, Math.PI*2, true);

  ctx.fill();

}


그 다음 각도 i의 값을 증가시킨다. 그리고 그 각도를 토대로 새 좌표 x,y를 만든다. 


여기까지가 한 사이클이다. 이후 10밀리세컨드가 지나면 init 함수가 draw 함수를 다시 호출하고, draw 함수는 점을 지운 다음 새 좌표에 점을 찍는다. 


근데, x, y를 계산하는 저 복잡한 공식은 무얼 의미할까?

우리의 목표는 점이 원모양으로 빙글빙글 돌게 만드는 것이다. 점이 원운동을 하려면 좌표가 원모양으로 변하도록 만들어야 한다.  그러려면 삼각 함수를 이용해서 좌표를 구해야 한다. 



단위원. 사진출처-위키피디아




따라서 x=cos(i), y=sin(i)가 된다. 


그럼 i를 구하는 저 복잡한 공식은 무얼 의미할까?

x와 y좌표가 원모양을 따라 변화하려면 각도 i가 증가해야 한다. 문제는 자바스크립트가 호도법의 각도 대신 ‘라디안’을 쓴다는 점이다. 따라서 i가 1도씩 늘어나게 해주려면 Math.PI/180(라디안으로 표현한 1도)을 더해주면 된다.