차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 다음 판 양쪽 다음 판 | ||
svg-work-2017 [2024/04/22 08:51] 14.63.160.16 이전 판으로 되돌림 (2024/02/22 15:44) |
svg-work-2017 [2024/05/04 21:54] 127.0.0.1 이전 판으로 되돌림 (2023/12/08 10:14) |
||
---|---|---|---|
줄 1: | 줄 1: | ||
+ | 1 | ||
+ | ==== 개요 ==== | ||
+ | 본 문서는 모니터링 대시보드에서 SVG를 다루기 위한 추가 개발에 고려된 기술적 내용을 담았다. | ||
+ | |||
+ | ==== 업데이트 요약 ==== | ||
+ | * 오브젝트 필터 적용: 객체 클래스에 ' | ||
+ | * 역방향 회전 적용: 패널 옵션에서 각 객체 항목의 ' | ||
+ | * 다중 패널 지원: 다중 패널을 추가해도 정상적으로 동작하도록 개선. | ||
+ | * SVG 개발 문서 작성: 객체 축좌표 계산, 애니메이션 키프레임 설명자 등의 내용이 담김. | ||
+ | |||
+ | ==== 구현 상세 ==== | ||
+ | * 구현: 스타일시트 동적 로딩 | ||
+ | CSS3에서 지원하는 스펙 사항을 플러그인에서 활용하기 위해 스타일시트(CSS)를 동적으로 요청할 필요성이 있다. jQuery를 이용하는 아래 구문으로 CSS의 동적 로드가 가능하다. | ||
+ | |||
+ | < | ||
+ | $("< | ||
+ | rel: " | ||
+ | type: " | ||
+ | href: this.panel.assets.basePath + '/' | ||
+ | }).appendTo(" | ||
+ | </ | ||
+ | |||
+ | CSS를 동적으로 로드해야 할 시에는 브라우저에 캐시로 남지 않도록 (만료 기간을 1회성으로 하기 위해) 랜덤 값 생성 함수를 같이 이용하여야 한다. 아래와 같은 랜덤 함수를 사용하면 된다. 랜덤 함수는 플러그인에서 상당히 많은 부분에 중요한 역할을 한다. | ||
+ | |||
+ | < | ||
+ | createRandomId(prefix, | ||
+ | var text = ""; | ||
+ | var possible = " | ||
+ | |||
+ | for (var i = 0; i < size; i++) { | ||
+ | text += possible.charAt(Math.floor(Math.random() * possible.length)); | ||
+ | } | ||
+ | |||
+ | return (prefix + text); | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * 구현: SVG 벡터 객체의 추적 및 다루기 | ||
+ | SVG 벡터 이미지는 XML 형식을 따르고 있다. SVG 벡터 이미지의 원활한 제어를 위해서는 SnapSVG-JS와 jQuery의 적절한 병행 이용이 필요하다. | ||
+ | |||
+ | < | ||
+ | var els = []; | ||
+ | var svg = Snap(" | ||
+ | var gs = svg.selectAll(' | ||
+ | gs.forEach(function(el) { | ||
+ | var $xml = $(el.toString()), | ||
+ | | ||
+ | | ||
+ | // thing 클래스만 목록으로 반환. | ||
+ | |||
+ | // 이미 ID를 가지고 있으며, 클래스가 thing 인것만 목록으로 넘김. | ||
+ | if(typeof($elmid) != ' | ||
+ | | ||
+ | } | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | * 구현: 키프레임 설명자를 이용한 회전 효과 | ||
+ | CSS3은 키프레임 설명자(KeyFrame-Descriptor)를 지원하여 애니메이션의 키프레임의 변화를 지정할 수 있다. 가령, 키프레임이 변형된 후 원형으로 돌아오는데 걸리는 시간을 지정하여 애니메이션 효과를 지정할 수 있다. 예제는 아래와 같다. | ||
+ | |||
+ | < | ||
+ | .rotate { | ||
+ | -webkit-animation: | ||
+ | -moz-animation: | ||
+ | -o-animation: | ||
+ | animation: rotation 2s infinite linear; | ||
+ | transform-origin: | ||
+ | -webkit-transform-origin: | ||
+ | -moz-transform-origin: | ||
+ | } | ||
+ | |||
+ | @-webkit-keyframes rotation { | ||
+ | from {-webkit-transform: | ||
+ | to | ||
+ | } | ||
+ | @-moz-keyframes rotation { | ||
+ | from {-moz-transform: | ||
+ | to | ||
+ | } | ||
+ | @-o-keyframes rotation { | ||
+ | from {-o-transform: | ||
+ | to | ||
+ | } | ||
+ | @keyframes rotation { | ||
+ | from {transform: rotate(0deg); | ||
+ | to | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 위 예제는 회전이 중앙 축을 기준으로 0도에서 359도 (약 360도) 회전하는데 걸리는 시간(원형 키프레임으로 돌아오는 시간)을 지정하여 회전 애니메이션 효과를 지정한다. 역방향 키프레임 효과는 목적 각도(deg of to)에 마이너스(-) 값을 주어서 구현이 가능하다. | ||
+ | 브라우저 벤더를 식별하는 문자로 webkit, moz, o 등이 존재하는데, | ||
+ | |||
+ | * 구현: 프리셋을 이용한 조건에 따른 효과 변화 | ||
+ | 프리셋을 통해 조건에 따른 애니메이션이나 색상 효과를 지정할 수 있다. 패널 옵션에서 프리셋의 속성을 바꿔치기(override) 할 수 있도록 지원하여 사용자가 직접 지정할 수 있다. | ||
+ | |||
+ | < | ||
+ | { | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 해당 속성을 바꿔치기(override)하는 것은 옵션 양식(editor.html)에서 입력을 지원하는 것으로도 가능하다. 또한 컨트롤러(ctrl.js)에서 override에 대한 더 상세한 조건을 코드로 지정할 수 있다. 아래는 override를 위해 사용자 값을 입력받는 양식의 예제이다. | ||
+ | |||
+ | < | ||
+ | <div class=" | ||
+ | <h5 class=" | ||
+ | <div class=" | ||
+ | <label class=" | ||
+ | <input type=" | ||
+ | </ | ||
+ | (... 생략 ...) | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | * 구현: 브라우저에서 표시되는 벡터 객체의 축좌표 계산 | ||
+ | SVG 벡터 이미지의 좌표 속성은 사후결정의 특징이 있어 축 좌표를 지정하기 위해 사전에 중간 값을 뜻하는 50%를 수치로 지정해놓아도 정확한 축 좌표를 찾지 않는다. | ||
+ | 즉 사후결정 방식에 맞게 객체 로드가 완료된 후 축 좌표를 계산하는 것이 필요하며 그 계산은 아래와 같이 가능하다. | ||
+ | |||
+ | < | ||
+ | // 중심 축좌표 계산 | ||
+ | var coord = s.getBBox(); | ||
+ | var cx = coord.x + (coord.width / 2); | ||
+ | var cy = coord.y + (coord.height / 2); | ||
+ | |||
+ | // 중심 축으로 회전 | ||
+ | var $node = $(s.node); | ||
+ | $node.addClass(" | ||
+ | $node.css({ | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | }); | ||
+ | </ | ||
+ | |||
+ | * 구현: 다중 패널의 구현 | ||
+ | 랜덤 값 생성 함수를 이용하여 다중 패널을 구현할 수 있다. 플러그인의 객체 생성자(플러그인 클래스의 생성자)에서 랜덤 값을 이용하여 캔버스 이름(SVG가 표현될 바탕이 될 객체의 이름)을 지정한다. 모듈 템플릿은 생성된 캔버스 이름을 가지고 객체를 생성한다. | ||
+ | |||
+ | < | ||
+ | export class [blind] extends [blind] | ||
+ | constructor($scope, | ||
+ | super($scope, | ||
+ | _.defaults(this.panel, | ||
+ | (... 생략 ....) | ||
+ | |||
+ | // 캔버스 코드 생성 | ||
+ | this.panel.canvasname = " | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | 이후 진행되는 과정은 앞서 명시된 SVG 벡터 객체 추적과 관련이 있으니 추가 개발 시 참고하면 된다. | ||
+ | |||
+ | * 적용: 컴파일 및 설치 방법 | ||
+ | 해당 플러그인의 컴파일(빌드) 명세는 grunt 빌드 환경에 의해 관리된다. 정상적인 빌드를 위해서는 각 프로젝트 내 디렉토리의 역할 및 작업을 지정할 필요가 있다. 아래는 빌드 시 실행될 작업(task)를 등록하는 예시이다. | ||
+ | |||
+ | < | ||
+ | (... 생략 ...) | ||
+ | assets: { | ||
+ | cwd: ' | ||
+ | expand: true, | ||
+ | src: [' | ||
+ | dest: ' | ||
+ | }, | ||
+ | extern: { | ||
+ | cwd: ' | ||
+ | expand: true, | ||
+ | src: [' | ||
+ | dest: ' | ||
+ | } | ||
+ | } | ||
+ | (... 생략 ...) | ||
+ | babel: { | ||
+ | options: { | ||
+ | sourceMap: true, | ||
+ | presets: [' | ||
+ | plugins: [' | ||
+ | }, | ||
+ | dist: { | ||
+ | files: [{ | ||
+ | cwd: ' | ||
+ | expand: true, | ||
+ | src: [' | ||
+ | dest: ' | ||
+ | ext: ' | ||
+ | }] | ||
+ | }, | ||
+ | }, | ||
+ | (... 생략 ...) | ||
+ | |||
+ | grunt.registerTask(' | ||
+ | </ | ||
+ | |||
+ | 빌드는 프로젝트 디렉토리에서 ‘grunt’ 명령을 이용한다. 해당 명령을 이용하면 아래와 같은 결과를 얻을 수 있다. 이후 프로젝트 디렉토리 전체를 / | ||
+ | |||
+ | < | ||
+ | root@compute:/ | ||
+ | Running " | ||
+ | >> 1 path cleaned. | ||
+ | |||
+ | (... 생략 ...) | ||
+ | |||
+ | Running " | ||
+ | Created 1 directory, copied 9 files | ||
+ | |||
+ | Running " | ||
+ | Created 2 directories, | ||
+ | |||
+ | Running " | ||
+ | |||
+ | Done, without errors. | ||
+ | </ | ||
+ | |||
+ | 동적 대시보드 개발 명세문서 마침. |