|
5 | 5 | } from 'vue'; |
6 | 6 | import { |
7 | 7 | assignedFixationColor, |
| 8 | + dropShadowInnerSize, |
8 | 9 | dropShadowOpacityEnd, |
9 | 10 | dropShadowOpacityStart, |
10 | 11 | dropShadowPasses, |
@@ -77,33 +78,72 @@ export const indicesRenderer = ( indicesCanvas: Ref<HTMLCanvasElement | null> ) |
77 | 78 | const draw = ( fixation: EditorFixation, idx: number, col: string ) => { |
78 | 79 | // Drop shadow |
79 | 80 | if ( dropShadowSize.value > 0 && dropShadowPasses.value > 0 ) { |
80 | | - const movePerIter = dropShadowSize.value / dropShadowPasses.value; |
| 81 | + // TODO: Start at smaller scale |
| 82 | + const movePerIterOutside = dropShadowSize.value / dropShadowPasses.value; |
| 83 | + const movePerIterInside = dropShadowInnerSize.value / dropShadowPasses.value; |
81 | 84 | const opacityPerStep = ( dropShadowOpacityStart.value - dropShadowOpacityEnd.value ) / dropShadowPasses.value; |
82 | | - const fontScaleUpPerIter = 2 * movePerIter; |
| 85 | + const fontScaleUpPerIterOutside = 2 * movePerIterOutside; |
| 86 | + const fontScaleUpPerIterInside = 2 * movePerIterInside; |
| 87 | + const numberToShow = ( idx + 1 ).toString(); |
83 | 88 |
|
84 | | - for ( let i = 0; i < dropShadowPasses.value; i++ ) { |
85 | | - const fontSize = scale( indicesFontSize.value + ( fontScaleUpPerIter * i ) ); |
| 89 | + let totalOffset = 0; |
86 | 90 |
|
87 | | - ctx!.font = fontSize + 'px ' + indicesFontFamily.value; |
88 | | - ctx!.fillStyle = `rgba( 0, 0, 0, ${ dropShadowOpacityStart.value + ( opacityPerStep * i ) } )`; |
89 | | - const aspect = ctx!.measureText( ( idx + 1 ).toString() ).width / fontSize; |
| 91 | + for ( let j = 0; j < numberToShow.length; j++ ) { |
| 92 | + const toDisplay = numberToShow[ j ]!; |
| 93 | + const width = ctx!.measureText( toDisplay ).width; |
| 94 | + |
| 95 | + // Outer shadow |
| 96 | + for ( let i = 0; i < dropShadowPasses.value; i++ ) { |
| 97 | + const fontSize = scale( indicesFontSize.value + ( fontScaleUpPerIterOutside * i ) ); |
| 98 | + |
| 99 | + ctx!.font = fontSize + 'px ' + indicesFontFamily.value; |
| 100 | + ctx!.fillStyle = `rgba( 0, 0, 0, ${ dropShadowOpacityStart.value + ( opacityPerStep * i ) } )`; |
| 101 | + const aspect = ctx!.measureText( toDisplay ).width / fontSize; |
| 102 | + |
| 103 | + ctx!.fillText( |
| 104 | + toDisplay, |
| 105 | + scale( originalToCanvasCoordinates( ( fixation.x! + fixationRadius.value ) - ( movePerIterOutside * i * aspect ), 'x' ) ) + totalOffset, |
| 106 | + scale( originalToCanvasCoordinates( ( fixation.y! - fixationRadius.value ) + ( movePerIterOutside * i ), 'y' ) ) |
| 107 | + ); |
| 108 | + } |
| 109 | + |
| 110 | + // Inner shadow |
| 111 | + for ( let i = 0; i < dropShadowPasses.value; i++ ) { |
| 112 | + const fontSize = scale( indicesFontSize.value - ( 2 * dropShadowInnerSize.value ) + ( fontScaleUpPerIterInside * i ) ); |
| 113 | + |
| 114 | + ctx!.font = fontSize + 'px ' + indicesFontFamily.value; |
| 115 | + ctx!.fillStyle = `rgba( 0, 0, 0, ${ dropShadowOpacityEnd.value - ( opacityPerStep * i ) } )`; |
| 116 | + const aspect = ctx!.measureText( toDisplay ).width / fontSize; |
| 117 | + |
| 118 | + ctx!.fillText( |
| 119 | + toDisplay, |
| 120 | + scale( originalToCanvasCoordinates( ( fixation.x! + fixationRadius.value ) - ( movePerIterInside * i * aspect ), 'x' ) ) + totalOffset, |
| 121 | + scale( originalToCanvasCoordinates( ( fixation.y! - fixationRadius.value ) + ( movePerIterInside * i ), 'y' ) ) |
| 122 | + ); |
| 123 | + } |
| 124 | + |
| 125 | + // Draw the actual number |
| 126 | + ctx!.font = 'bold ' + scale( indicesFontSize.value ) + 'px ' + indicesFontFamily.value; |
| 127 | + ctx!.fillStyle = col; |
90 | 128 |
|
91 | 129 | ctx!.fillText( |
92 | | - ( idx + 1 ).toString(), |
93 | | - scale( originalToCanvasCoordinates( ( fixation.x! + fixationRadius.value ) - ( movePerIter * i * aspect ), 'x' ) ), |
94 | | - scale( originalToCanvasCoordinates( ( fixation.y! - fixationRadius.value ) + ( movePerIter * i ), 'y' ) ) |
| 130 | + toDisplay, |
| 131 | + scale( originalToCanvasCoordinates( fixation.x! + fixationRadius.value, 'x' ) ) + totalOffset, |
| 132 | + scale( originalToCanvasCoordinates( fixation.y! - fixationRadius.value, 'y' ) ) |
95 | 133 | ); |
| 134 | + |
| 135 | + totalOffset += width; |
96 | 136 | } |
| 137 | + } else { |
| 138 | + ctx!.font = 'bold ' + scale( indicesFontSize.value ) + 'px ' + indicesFontFamily.value; |
| 139 | + ctx!.fillStyle = col; |
| 140 | + |
| 141 | + ctx!.fillText( |
| 142 | + ( idx + 1 ).toString(), |
| 143 | + scale( originalToCanvasCoordinates( fixation.x! + fixationRadius.value, 'x' ) ), |
| 144 | + scale( originalToCanvasCoordinates( fixation.y! - fixationRadius.value, 'y' ) ) |
| 145 | + ); |
97 | 146 | } |
98 | | - |
99 | | - ctx!.font = 'bold ' + scale( indicesFontSize.value ) + 'px ' + indicesFontFamily.value; |
100 | | - ctx!.fillStyle = col; |
101 | | - |
102 | | - ctx!.fillText( |
103 | | - ( idx + 1 ).toString(), |
104 | | - scale( originalToCanvasCoordinates( fixation.x! + fixationRadius.value, 'x' ) ), |
105 | | - scale( originalToCanvasCoordinates( fixation.y! - fixationRadius.value, 'y' ) ) |
106 | | - ); |
107 | 147 | }; |
108 | 148 |
|
109 | 149 | watch( [ |
|
0 commit comments