프론트엔드

Raphael로 웹에 낙서를 해봅시다.

CyberI 2016. 6. 14. 22:14


RaphaelJS는?

RaphaelJS는 IE8 이하의 브라우저에서 SVG를 사용하게 하기위한 오픈소스 라이브러리 입니다.
즉, 하위 브라우저에서는 VML로 변환시켜 줌으로써, 국내 브라우저 환경을 대응 할 수 있도록 하는 감사한 
Cross-browser를 돕는 adapter 입니다.


현재는 http://dmitrybaranovskiy.github.io/raphael/ 라는 github 에서 관리, 배포되고 있습니다.


기본  사용법

  1. SVG가 사용될 영역 엘리먼트를 만듭니다.
  2. 영역 엘리먼트와 넓이, 높이를 지정하여 라파엘을 초기화 합니다.
  3. 그리고 그립니다.

/* 영역 엘리먼트 작성 */
<div id="svg"></div>

<script type="text/javascript">
// SVG 생성 - Raphael 초기화
var paper = Raphael(document.getElementByID('svg'), 320, 200);
// 나는 SVG에 원을 그릴 것입니다.
var circle = paper.circle(50, 40, 10);
</script>


결과> 크롬브라우저


결과> IE11에서 개발자도구로 IE8 버전


이렇게 <div id="svg"></div> 안에 SVG 또는 VML이 자동생성 됩니다.


제공하는 기본 모형

라파엘에서 제공하는 기본 모형으로는 원, 타원, 사각이 있습니다. 다른 모형은 path로 직접 작성해야 합니다.

//  원                       (x 중심 좌표값, y 중심 좌표값, 반지름);

var circle = paper.circle(50, 50, 40);

//  타원                    (x 중심 좌표값, y 중심 좌표값, 세로 반지름, 가로 반지름);

var ellipse = paper.ellipse(150, 50, 40, 20);

//  사각                    (x 좌표값, y 좌표값, 넓이, 높이);

var rect1 = paper.rect(50, 150, 40, 40);

//  코너가 둥근 사각    (x 좌표값, y 좌표값, 넓이, 높이, 코너 둥글기);

var rect2 = paper.rect(150, 150, 40, 40, 10);


결과 >


기본적으로 svg의 좌표값이나 지름 등의 단위는 최소 1PX이며 색상은 검정색입니다. 


그런데 말입니다.

크롬에서 원은 괜찮은데  1px인데도 불구하고 사각형에서 1px이 아닌 흐릿한 회색빛의 2px가량 되는 선으로 그려진것을 확인할 수 있습니다. 환장하게도 IE8은 깨끗한 1px로 그려지는데 말이죠.


여기서 우리는 브라우저를 체크해서 IE8이하인 경우와 아닌 경우를 구분할 필요가 있습니다.


if(브라우저 IE8이하가 아니거나 최신브라우저이면){


var rect1 = paper.rect(50.5, 150.5, 40, 40);


var rect2 = paper.rect(150.5, 150.5, 40, 40, 10);

} else {


var rect1 = paper.rect(50, 150, 40, 40);


var rect2 = paper.rect(150, 150, 40, 40, 10);

}


브라우저를 체크할 수 있는 스크립트는 검색하면 많이 나오므로 이번 포스팅에는 적지 않겠습니다.


(결코 귀찮아서가 아닙니다..하하하)


아래는 제가 사용한 방식입니다.

이 TYPE으로 if문을 분기하였습니다.


var g = {doc: document, win: window};

var TYPE = (g.win.SVGAngle || g.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML");




다시 선에 관한 본문으로 돌아와서.. 차이점을 바로 알아채셨나요?


즉, VML이 아닌 환경에서는 좌표값에 0.5를 더하여 주면 깨끗하고 맑은 1px의 선을 확인 하실 수 있습니다.


결과 >



이번엔, path를 이용하여 도형을 만들어보도록 하겠습니다.


도형하면 별, 별은 스타 뭐 그런거 아니겠습니까.


/**

centerX : x 중심 좌표

centerY : y 중심 좌표

arms : 별에 삐죽한 부분 개수

outerRadius : 별 크기

innerRadius : 별의 꺽이는 각도

*/

function drawStar(centerX, centerX, arms, outerRadius, innerRadius){

var results = "";


var angle = Math.PI / arms;


for (var i = 0; i < 2 * arms; i++) {

var r = (i & 1) == 0 ? outerRadius : innerRadius;


var currX = centerX + Math.cos(i * angle) * r;

var currY = centerY + Math.sin(i * angle) * r;


if (i == 0) {

results = currX + " " + currY;

} else {

results += " L" + currX + " " + currY;

}

}


return results;

}

// 별을 그려보자.

var star = paper.path('M' + drawStar(50, 50, 5, 20, 10) + 'Z');


결과 >


Path

path는 좌표값을 가진 문자열입니다.

"M10,20L30,40"


위의 예시처럼 각각의 좌표는 Comma(,)로 구분합니다.


알파벳은 Command라고 불리며, 대문자로 선언하면 absolute, 소문자로 선언하면 relative 상태를 표현한다고 합니다.


주로 사용하는 Command를 설명하자면,


 M

 path의 시작점

 Mx,y 

 L

 path의 이동

 이 값만큼 선이 그려집니다.

 Lx,y 

 Z 

 path를 닫습니다.

 이 글자를 선언하지 않는다면 Element를 그릴때 열려있는 형태로 그려집니다.

 


더 많은 자세한 Command를 알고 싶다면 아래의 링크에서 확인하실 수 있습니다.


w3.org - https://www.w3.org/TR/SVG/paths.html#PathData



Styling

자, 이제 스타일을 입혀보도록 하겠습니다.


보통 면의 색상과 투명도, 선의 색상, 투명도, 두께 정도를 변경할 것입니다.


raphael에서는 jQuery처럼 여러개의 스타일을 한번에 선언할 수 있습니다.

다만 저는 스타일 변경이라고 했지만 SVG 얘는 속성을 변경하는 거라 attr()을 쓴다는 것만 기억하면 되겠습니다.


star.attr({


fill : '#ffea00',         // 면색상

fill-opacity : 1,        // 면 색 투명도


stroke : '#ff7e00',    // 선색상

stroke-opacity : 1,   // 선 색 투명도

stroke-width : 3,     // 선 두께


opacity : 1            // element 자체 투명도

});


결과 >


면의 색상에는 Solid Color와 Gradient 또는 이미지를 사용 할 수 있습니다.


Solid Color

  • Color Name : 'red', 'blue' 등
  • Hex : '#000', '#ffffff' 등
  • rgb : 'rgb(red channel 0 ~ 255, green channel 0 ~ 255, blue channel 0 ~ 255)'
  • rgba : 'rgba(red channel 0 ~ 255, green channel 0 ~ 255, blue channel 0 ~ 255, alpha 0 ~ 1)'
  • 이 외에도 hsb, hsba, hsl, hsla 가 있습니다.
1. fill : 'red'
2. fill : '#ffea00'
3. fill : 'rgb(66, 149, 66)'
4. fill : 'rgba(66, 149, 66, 0.5)'



결과 > 


4번의 경우 투명도 확인차 두개의 Element를 겹쳐보았습니다.


rgba를 사용할 경우 fill-opacity가 동시에 적용되어 있다면 fill-opacity가 우선순위에 있게 됩니다. 

즉, rgba의 alpha값을 아무리 낮춰도 적용되지 않습니다. 

둘 중 하나는 지워주세요.

Gradient

  • Linear Gradient : "<angle>-<color>[-color>[:<offset>]]*-<color>"
  • Radial Gradient : "r[(<fx>, <fy>)]<color>[-<color>[:<offset>]]*-<color>"

1. paper.rect(...).attr({ fill : '90-#fff-#000' });

2. paper.rect(...).attr({ fill : '0-#fff-#ff0:20-#000' });

3. paper.circle(...).attr({ fill : 'r#fff-#000' });

4. paper.circle(...).attr({ fill : 'r(0.25, 0.75)#fff-#000' });


결과 >


Image

paper.rect(...).attr({ fill : 'url(이미지 경로)' });


결과 >




1. 스쳐지나가듯이 Raphael을 초기화하고

2. 간단한 도형을 그려보고

3. 안이쁘게 스타일도 적용해 보았습니다.



그럼, 다음 시간에 뵙겠습니다!