Skip to content

Commit 4f13301

Browse files
committed
[Editor] Add auto scroll for fixations and zoom to fixation instead of origin
1 parent 2314c67 commit 4f13301

File tree

6 files changed

+72
-29
lines changed

6 files changed

+72
-29
lines changed

notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
- [X] Backspace moves backwards if no annotation present
4646
- [X] Space bar assignment doesn't work (on Mac at least) --> TODO: Verify
4747
- [ ] Optional: Show zoom box if lots of fixations close by
48-
- [ ] Zoom to fixation
49-
- [ ] Move to fixation when moving around (and zoom factor > 1)
48+
- [X] Zoom to fixation
49+
- [X] Move to fixation when moving around (and zoom factor > 1)
5050
- [ ] **Render hovered boxes above everything else (to make it more legible, maybe add condition to this)**
5151

5252

src/editor/data/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
ref
44
} from 'vue';
55
import type {
6-
EditorAnnotation
6+
EditorAnnotation,
7+
EditorPoint
78
} from '../types/annotation';
89
import type {
910
EditorCharacterBoundingBox
@@ -52,6 +53,9 @@ export const canvasSize = ref( {
5253
...referenceCanvasSize
5354
} );
5455

55-
export const originalSize = ref( {
56+
export const originalSize: Ref<{
57+
'width': number;
58+
'height': number;
59+
}> = ref( {
5660
...referenceCanvasSize
5761
} );

src/editor/io/keyboard.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ import {
77
} from '../config';
88
import {
99
annotations,
10-
fixations,
1110
selectedFixation
1211
} from '../data';
12+
import {
13+
goToNextFixation,
14+
goToPrevFixation
15+
} from '../manager/fixations';
1316
import {
1417
onMounted,
1518
onUnmounted
@@ -72,9 +75,7 @@ export const keyboardHandler = ( renderer: Renderer ) => {
7275
} else if ( ( ev.key === 'Backspace' || ev.key === 'Delete' ) && !ev.shiftKey ) {
7376
// Delete annotation or move back
7477
if ( !annotation.deleteByFixID( selectedFixation.value, true ) ) {
75-
if ( selectedFixation.value > -1 ) {
76-
selectedFixation.value = mod( selectedFixation.value - 1, fixations.value.length );
77-
}
78+
goToPrevFixation();
7879
}
7980
} else if ( ev.key === 's' && ( ev.ctrlKey || ev.metaKey ) ) {
8081
// Save
@@ -103,14 +104,10 @@ export const keyboardHandler = ( renderer: Renderer ) => {
103104
}
104105
} else if ( ev.key === 'ArrowRight' ) {
105106
// Move to next fixation
106-
if ( selectedFixation.value > -1 ) {
107-
selectedFixation.value = mod( selectedFixation.value + 1, fixations.value.length );
108-
}
107+
goToNextFixation();
109108
} else if ( ev.key === 'ArrowLeft' ) {
110109
// Move to previous fixation
111-
if ( selectedFixation.value > -1 ) {
112-
selectedFixation.value = mod( selectedFixation.value - 1, fixations.value.length );
113-
}
110+
goToPrevFixation();
114111
} else if ( ( ev.key === 'Delete' || ev.key === 'Backspace' ) && ev.shiftKey ) {
115112
// Mark a fixation as invalid
116113
ev.preventDefault();
@@ -175,11 +172,3 @@ const isRedoCmd = ( event: KeyboardEvent ) => {
175172
return ( ( event.ctrlKey || event.metaKey ) && event.key.toLowerCase() === 'y' )
176173
|| ( ( event.ctrlKey || event.metaKey ) && event.shiftKey && event.key.toLowerCase() === 'z' );
177174
};
178-
179-
/**
180-
* Computes the modulo of a number because JS is too stupid to do it properly
181-
* @param val - The value to compute for
182-
*/
183-
const mod = ( val: number, mod: number ) => {
184-
return ( ( val % mod ) + mod ) % mod;
185-
};

src/editor/manager/fixations.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1+
import {
2+
fixations,
3+
hoveredFixation,
4+
selectedFixation,
5+
zoomFactor
6+
} from '../data';
17
import type {
28
EditorPoint
39
} from '../types/annotation';
410
import {
511
getFixationIdByCoodianate
612
} from '../association/fixations';
713
import {
8-
hoveredFixation
9-
} from '../data';
14+
mod
15+
} from '../util/arithmetic';
16+
import zoom from './zoom';
1017

1118
// Sets the hovered fixation and returns if false if one is hovered
1219
// (Why? See move manager)
@@ -17,3 +24,24 @@ export const fixationHighlightHandler = ( pos: EditorPoint ): boolean => {
1724

1825
return false;
1926
};
27+
28+
export const goToNextFixation = () => {
29+
selectFixation( selectedFixation.value + 1 );
30+
};
31+
32+
export const goToPrevFixation = () => {
33+
selectFixation( selectedFixation.value - 1 );
34+
};
35+
36+
const selectFixation = ( val: number ) => {
37+
if ( selectedFixation.value > -1 ) {
38+
selectedFixation.value = mod( val, fixations.value.length );
39+
40+
if ( zoomFactor.value > 1 ) {
41+
zoom.setViewPortOriginFromCenter( {
42+
'x': fixations.value[ selectedFixation.value ]!.x!,
43+
'y': fixations.value[ selectedFixation.value ]!.y!
44+
} );
45+
}
46+
}
47+
};

src/editor/manager/zoom.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {
22
canvasPosition,
3+
fixations,
34
originalSize,
5+
selectedFixation,
46
zoomFactor
57
} from '../data';
68
import {
@@ -36,9 +38,12 @@ const setViewPortOriginFromCenter = ( target: EditorPoint ) => {
3638
// translate to percentages (canvasPosition is in percentages)
3739
// Try to center target in the viewport
3840
canvasPosition.value = {
39-
'x': toPercentageOfOriginal( limiter( originFromCenter( target.x, 'width' ), 'width' ), 'width' ),
40-
'y': toPercentageOfOriginal( limiter( originFromCenter( target.y, 'height' ), 'height' ), 'height' )
41+
'x': roundToDigits( toPercentageOfOriginal( limiter( centerCoordinateInViewPort( target.x, 'width' ), 'width' ), 'width' ) ),
42+
'y': roundToDigits( toPercentageOfOriginal( limiter( centerCoordinateInViewPort( target.y, 'height' ), 'height' ), 'height' ) )
4143
};
44+
console.log( {
45+
...canvasPosition.value
46+
} );
4247
};
4348

4449
/**
@@ -68,8 +73,10 @@ const toPercentageOfOriginal = ( val: number, side: 'width' | 'height' ) => {
6873
};
6974

7075
/** Get the origin coordinate of the text from the center */
71-
const originFromCenter = ( val: number, side: 'width' | 'height' ) => {
72-
return val - ( originalSize.value[ side ] / 2 );
76+
const centerCoordinateInViewPort = ( val: number, side: 'width' | 'height' ) => {
77+
const shownPixels = originalSize.value[ side ] / zoomFactor.value;
78+
79+
return val - ( shownPixels / 2 );
7380
};
7481

7582
/** Sets limits for the zoom move (i.e. so you can't move the entire text out of view */
@@ -106,7 +113,13 @@ const setFactor = ( factor: number ) => {
106113

107114
// NOTE: If you want to do relative to mouse position,
108115
// add a mouse position in here and use setViewPortOriginFromCenter
109-
setViewPortOrigin( getViewPortOrigin() );
116+
if ( selectedFixation.value < 0 )
117+
setViewPortOrigin( getViewPortOrigin() );
118+
else
119+
setViewPortOriginFromCenter( {
120+
'x': fixations.value[ selectedFixation.value ]!.x!,
121+
'y': fixations.value[ selectedFixation.value ]!.y!
122+
} );
110123
};
111124

112125
/** Returns the zoom factor */

src/editor/util/arithmetic.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,12 @@ import type {
55
export const distanceBetweenPoints = ( p1: EditorPoint, p2: EditorPoint ) => {
66
return Math.sqrt( Math.pow( p1.x - p2.x, 2 ) + Math.pow( p1.y - p2.y, 2 ) );
77
};
8+
9+
10+
/**
11+
* Computes the modulo of a number because JS is too stupid to do it properly
12+
* @param val - The value to compute for
13+
*/
14+
export const mod = ( val: number, mod: number ) => {
15+
return ( ( val % mod ) + mod ) % mod;
16+
};

0 commit comments

Comments
 (0)