Panolens compass

Compass

panolens에는 따로 지원하지 않는 것 같다. 그래서 직접 구현해보기했다.

google tour 에서 볼 수 있는 나침판처럼 동작을 하면 된다 . c2 누가 나침판 이미지를 만들어 주는게 아니니까 google tour으로 접속해서 나침판에 사용된 이미지를 다운받아 준비를 해뒀다. 기본적으로 panolens에서 버튼을 생성하는 아래 방식처럼 compass를 추가하길 원했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type="text/javascript">
    var panorama = new PANOLENS.BasicPanorama(10000);
    var options = {
            'controlButtons':['fullscreen''setting''video''compass'],
            'output''console'
    }
    var viewer = new PANOLENS.Viewer(options); 
    myInfospot = new PANOLENS.Infospot();
    myInfospot.position.set( 0-50000 );
    myInfospot.setCursorHoverStyle( 'pointer' ); // set infospot hover style 
    
    panorama.add(myInfospot);
    
    viewer.add(panorama);
    
</script>
cs

옵션에 controlButtons 항목에 배열로 compass를 추가하면 자동으로 딱! 하고 나오게 말이다.

소스분석

controlButtons를 시작으로 검색을 시작했다.

addControlBar의 bar.dispose에 compassElement 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
bar.dispose = function () {
    if ( scope.fullscreenElement ) {
        bar.removeChild( scope.fullscreenElement );
        scope.fullscreenElement.dispose();
        scope.fullscreenElement = null;
    }
    if ( scope.settingElement ) {
        bar.removeChild( scope.settingElement );
        scope.settingElement.dispose();
        scope.settingElement = null;
    }
    if ( scope.videoElement ) {
        bar.removeChild( scope.videoElement );
        scope.videoElement.dispose();
        scope.videoElement = null;
    }
    
    /*
     * 작성자: silqwer
     * 설명: 나침판 배치
     */
    if (scope.compassElement) {
        bar.removeChild( scope.compassElement );
        scope.compassElement.dispose();
        scope.compassElement = null;
    }
};
cs

기존에 버튼을 추가하는 로직과 동일하게 맞쳐준다.

addControlButton에 compass 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * Add buttons on top of control bar
 * @param {string} name - The control button name to be created
 */
PANOLENS.Widget.prototype.addControlButton = function ( name ) {
 
    var element;
 
    switchname ) {
 
        case 'fullscreen':
 
            element = this.createFullscreenButton();
            this.fullscreenElement = element; 
 
            break;
 
        case 'setting':
 
            element = this.createSettingButton();
            this.settingElement = element;
 
            break;
 
        case 'video':
 
            element = this.createVideoControl();
            this.videoElement = element;
 
            break;
        
        /*
         * 작성자: silqwer
         * 설명: 나침판 생성
         */
        case 'compass':
            element = this.createCompass();
            this.compassElement = element;
            
            break;
 
        default:
 
            return;
 
    }
 
    if ( !element ) {
 
        return;
 
    }
 
    this.barElement.appendChild( element );
 
};
cs

기존에 버튼을 생성해주는 방식과 동일하게 case를 추가하고 this.createCompass()를 만든다.

createCompass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
 * 작성자: silqwer
 * 설명: 나침판 생성
 */
PANOLENS.Widget.prototype.createCompass = function () {
 
    var scope = this;
    var item = this.createCustomItem( { 
 
        style : { 
 
            float : 'left',
            cursor :'default'
        },
 
    } );
    
    item.background = this.createCompassBackground();
    item.innerDot = this.createCompassInnerDot();
    item.innerView = this.createCompassInnerView();
    item.outerRing = this.createCompassOuterRing();
    
    item.appendChild( item.background );
    item.appendChild( item.innerDot );
    item.appendChild( item.innerView );
    item.appendChild( item.outerRing );
    
    return item;
 
};
cs

createVideoControl를 참고해서 createCompass 작성했다. compass의 경우 4장의 이미지가 필요하고 innerView에 해당하는 이미지가 카메라가 돌아갈 때마다 회전을 해야한다.

createCompassBackground() 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 작성자: silqwer
 * 설명: 나침판 백그라운 이미지 요소 
 */
PANOLENS.Widget.prototype.createCompassBackground = function () {
    var item;
    
    item = this.createCustomItem( { 
 
        style : { 
 
            float : 'left',
            backgroundImage : 'url("' + PANOLENS.DataImage.CompassBackground + '")'
            cursor: 'default'
            position: 'absolute'
 
        }
 
    } );
    
    return item;
};
cs

여기서 보면 PANOLENS.DataImage.CompassBackground으로 경로를 가져오는 걸 볼 수 있는데 panolens에서 이미지 리소스를 가져올 때 따로 파일로 저장하지 않고 base64로 변환을 해서 스크립트에 포함 시켰다.

이미지 리소스 변환

이미지 파일을 base64로 변환을 시켜주는 사이트( https://www.base64-image.de/ )에서 변환한 뒤에 PANOLENS.DataImage에 추가 시켰다.

createCompassInnerDot ()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 작성자: silqwer
 * 설명: 나침판 점 이미지 요소 
 */
PANOLENS.Widget.prototype.createCompassInnerDot = function () {
    var item;
    
    item = this.createCustomItem( { 
 
        style : { 
 
            float : 'left',
            backgroundImage : 'url("' + PANOLENS.DataImage.CompassInnerDot + '")',
            cursor: 'default'
            position: 'absolute'
 
        }
 
    } );
    
    return item;
};
cs

createCompassInnerView ()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
 * 작성자: silqwer
 * 설명: 나침판 시점 이미지 요소 
 */
PANOLENS.Widget.prototype.createCompassInnerView = function () {
    var item;
    var scope = this; 
    
    item = this.createCustomItem( { 
 
        style : { 
 
            float : 'left',
            backgroundImage : 'url("' + PANOLENS.DataImage.CompassInnerView + '")',
            cursor: 'default'
            position: 'absolute'
 
        }
 
    } );
    
    scope.dispatchEvent( { type: 'panolens-viewer-handler', method: 'onRotationChange', data: item } );
    
    return item;
};
cs

dispatchEvent를 통해서 onRotationChange 함수 호출

onRotationChange ()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * 작성자: silqwer
 * 설명: 나침판 회전 함수
 */
PANOLENS.Viewer.prototype.onRotationChange = function (element){
    
    var camera = this.camera;
    
    this.control.addEventListener('change'function(){
        
        var rotationY = camera.rotation.y;
        var dy = 0
        
        if ( rotationY < 0 ){
            dy = THREE.Math.radToDeg( rotationY + ( 2 * Math.PI ) );
        }else{
            dy = THREE.Math.radToDeg( rotationY );
        }
        
        dy = Math.round(dy) * -1;
        element.style.transform = 'rotate('+ (dy % 360+'deg)';
    }, false);
    
};
cs

createCompassOuterRing ()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
 * 작성자: silqwer
 * 설명: 나침판 틀 이미지 요소 
 */
PANOLENS.Widget.prototype.createCompassOuterRing = function () {
    var item;
    
    item = this.createCustomItem( { 
 
        style : { 
 
            float : 'left',
            backgroundImage : 'url("' + PANOLENS.DataImage.CompassOuterRing + '")',
            cursor: 'default'
            position: 'absolute'
 
        }
 
    } );
    
    return item;
};
cs

결과

c3