svj.js를 활용한 interaction 예제 구현
1.초기 Frame영역 설정, rect형태로 Frame size 선언
var SVG = require('svg.js');
var svgdraw = SVG("drawing").size(300, 300);
var rectFrame = {
left: 0,
top: 0,
right: svgdraw.width(),
bottom: svgdraw.height()
};
2.svg line
객체로 frame 그리기, 추후 line svg를 통해 intersecion 검사 수행
var frameLines = []
frameLines.push(svgdraw.line(rectFrame.left, rectFrame.top, rectFrame.left, rectFrame.bottom).attr({stroke:"black"}));
frameLines.push(svgdraw.line(rectFrame.left, rectFrame.bottom, rectFrame.right, rectFrame.bottom).attr({stroke:"black"}));
frameLines.push(svgdraw.line(rectFrame.right, rectFrame.bottom, rectFrame.right, rectFrame.top).attr({stroke:"black"}));
frameLines.push(svgdraw.line(rectFrame.right, rectFrame.top, rectFrame.left, rectFrame.top).attr({stroke:"black"}));
3. browser의 refresh에 맞춰 draw 추가
function OnDraw() {
window.requestAnimationFrame(OnDraw);
// svgdrawing code goes here
frameCount++;
}
OnDraw();
4. 1초 단위로 frame rate 출력
///Frame Rate
var textFrameRate = svgdraw.text('Frame Rate: 0 f/s');
textFrameRate.move(svgdraw.width()-150, svgdraw.height()-25);
//Frame rate
setInterval(function(){
frameRate = frameCount;
frameCount = 0;
textFrameRate.text("Frame Rate: " + frameRate + " f/s");
}, 1000);
5. Random하게 circle svg
객체 생성 하기
circleSize = 20;
circleCount = 6;
colors = ["red", "blue", "yellow", "black","#F80","#80F"]
for(var i=0; i<circleCount; i++)
{
posX[i] = Math.floor((Math.random() * svgdraw.width()) - circleSize);
posY[i] = Math.floor((Math.random() * svgdraw.height()) - circleSize);
if(posX[i] < 0) posX[i]=0;
if(posY[i] < 0) posY[i]=0;
circles[i] = svgdraw.circle(circleSize).attr({fill: colors[i]}).move(posX[i], posY[i]);
}
6. source circle객체 마다 다른 cicle객체 충돌 검사, frame 외벽 검사 수행
for(var src=0; src<circles.length; src++)
{
var isIntersect = false;
var srcObj, destObj;
srcObj = circles[src];
///Circle
for(var dest=0; dest<circles.length; dest++)
{
if(src == dest) continue;
if(intersectRect(circles[src], circles[dest]))
{
isIntersect = true;
destObj = circles[dest];
break;
}
}
///Frame
if(!isIntersect)
{
for(var f=0; f<frameLines.length; f++)
{
if(intersectRect(circles[src], frameLines[f]))
{
isIntersect = true;
destObj = frameLines[f];
break;
}
}
}
}
7. 충돌이라고 판단되면, 방향 전환
원래는 충돌 면에 따라 움직이는 방향을 정해야 하지만, 임시 테스트 이기에 충돌 없을때까지 무작위로 수행
if(isIntersect)
{
var tryCount = 0;
while(intersectRect(srcObj, destObj))
{
if(tryCount++ > 10)
break;
changeDirection(src);
moveCircle(src);
}
}
8.초기 생성시에 random위치 생성시 서로 충돌 나는 예외처리 추가
반복적으로 생성 하면서 충돌시 재생성
for(var i=0; i<circleCount; i++)
{
var cir = createCircle(i);
for(var dest=0; dest<circles.length; dest++)
{
if(!intersectRect(cir.circle, circles[dest]))
break;
cir.circle.remove();
dest--;
cir = createCircle(i);
}
posX[i] = cir.posX;
posY[i] = cir.posY;
circles[i] = cir.circle;
dirs[i] = Math.floor((Math.random() * 4));
changeDelta(i, dirs[i]);
}
9.전체 source는 github에 (https://github.com/scanhand/test_svgjs)
10.결과 화면