protected _enable()

in src/component/keyboard/KeySpatialNavigationHandler.ts [68:142]


    protected _enable(): void {
        const spatialEdges$: Observable<NavigationEdgeStatus> = this._navigator.stateService.currentImage$.pipe(
            switchMap(
                (image: Image): Observable<NavigationEdgeStatus> => {
                    return image.spatialEdges$;
                }));

        this._keyDownSubscription = this._container.keyboardService.keyDown$.pipe(
            withLatestFrom(
                spatialEdges$,
                this._navigator.stateService.currentState$))
            .subscribe(([event, edgeStatus, frame]: [KeyboardEvent, NavigationEdgeStatus, AnimationFrame]): void => {
                let spherical = isSpherical(frame.state.currentImage.cameraType);
                let direction: NavigationDirection = null;
                switch (event.keyCode) {
                    case 37: // left
                        direction = event.shiftKey && !spherical ? NavigationDirection.TurnLeft : NavigationDirection.StepLeft;
                        break;
                    case 38: // up
                        direction = event.shiftKey && !spherical ? NavigationDirection.Spherical : NavigationDirection.StepForward;
                        break;
                    case 39: // right
                        direction = event.shiftKey && !spherical ? NavigationDirection.TurnRight : NavigationDirection.StepRight;
                        break;
                    case 40: // down
                        direction = event.shiftKey && !spherical ? NavigationDirection.TurnU : NavigationDirection.StepBackward;
                        break;
                    default:
                        return;
                }

                event.preventDefault();

                if (event.altKey || !edgeStatus.cached ||
                    (event.shiftKey && spherical)) {
                    return;
                }

                if (!spherical) {
                    this._moveDir(direction, edgeStatus);
                } else {
                    const shifts: { [dir: number]: number } = {};

                    shifts[NavigationDirection.StepBackward] = Math.PI;
                    shifts[NavigationDirection.StepForward] = 0;
                    shifts[NavigationDirection.StepLeft] = Math.PI / 2;
                    shifts[NavigationDirection.StepRight] = -Math.PI / 2;

                    const phi: number = this._rotationFromCamera(frame.state.camera).phi;
                    const navigationAngle: number = this._spatial.wrapAngle(phi + shifts[direction]);
                    const threshold: number = Math.PI / 4;
                    const edges: NavigationEdge[] = edgeStatus.edges.filter(
                        (e: NavigationEdge): boolean => {
                            return e.data.direction === NavigationDirection.Spherical || e.data.direction === direction;
                        });

                    let smallestAngle: number = Number.MAX_VALUE;
                    let toKey: string = null;
                    for (const edge of edges) {
                        const angle: number = Math.abs(this._spatial.wrapAngle(edge.data.worldMotionAzimuth - navigationAngle));

                        if (angle < Math.min(smallestAngle, threshold)) {
                            smallestAngle = angle;
                            toKey = edge.target;
                        }
                    }

                    if (toKey == null) {
                        return;
                    }

                    this._moveTo(toKey);
                }
            });
    }