react-msaview 5.1.1 → 5.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +41 -8
  2. package/bundle/index.js +17 -17
  3. package/bundle/index.js.LICENSE.txt +1 -1
  4. package/bundle/index.js.map +1 -1
  5. package/dist/calculateBlocks.d.ts +4 -10
  6. package/dist/calculateBlocks.js +12 -20
  7. package/dist/calculateBlocks.js.map +1 -1
  8. package/dist/components/ConservationTrack.js +20 -37
  9. package/dist/components/ConservationTrack.js.map +1 -1
  10. package/dist/components/MSAView.js +8 -1
  11. package/dist/components/MSAView.js.map +1 -1
  12. package/dist/components/ResizeHandles.d.ts +3 -0
  13. package/dist/components/ResizeHandles.js +60 -105
  14. package/dist/components/ResizeHandles.js.map +1 -1
  15. package/dist/components/TextTrack.js +25 -34
  16. package/dist/components/TextTrack.js.map +1 -1
  17. package/dist/components/Track.js +1 -1
  18. package/dist/components/Track.js.map +1 -1
  19. package/dist/components/VerticalScrollbar.js +2 -2
  20. package/dist/components/VerticalScrollbar.js.map +1 -1
  21. package/dist/components/dialogs/ExportSVGDialog.js +20 -20
  22. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  23. package/dist/components/dialogs/InterProScanDialog.js +6 -1
  24. package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
  25. package/dist/components/dialogs/UserProvidedDomainsDialog.js +1 -2
  26. package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -1
  27. package/dist/components/header/ColorSchemeMenu.js +1 -1
  28. package/dist/components/header/ColorSchemeMenu.js.map +1 -1
  29. package/dist/components/header/FileMenu.js +3 -2
  30. package/dist/components/header/FileMenu.js.map +1 -1
  31. package/dist/components/header/Header.js +1 -1
  32. package/dist/components/header/HeaderInfoArea.js +28 -8
  33. package/dist/components/header/HeaderInfoArea.js.map +1 -1
  34. package/dist/components/header/MSASettingsMenu.js +1 -1
  35. package/dist/components/header/MSASettingsMenu.js.map +1 -1
  36. package/dist/components/header/TreeSettingsMenu.js +1 -1
  37. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  38. package/dist/components/header/ZoomControls.js +7 -2
  39. package/dist/components/header/ZoomControls.js.map +1 -1
  40. package/dist/components/header/ZoomMenu.js +9 -0
  41. package/dist/components/header/ZoomMenu.js.map +1 -1
  42. package/dist/components/header/settingsMenuItems.js +24 -8
  43. package/dist/components/header/settingsMenuItems.js.map +1 -1
  44. package/dist/components/minimap/Minimap.js +6 -17
  45. package/dist/components/minimap/Minimap.js.map +1 -1
  46. package/dist/components/minimap/MinimapSVG.js +7 -17
  47. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  48. package/dist/components/minimap/minimapLayout.d.ts +9 -0
  49. package/dist/components/minimap/minimapLayout.js +15 -0
  50. package/dist/components/minimap/minimapLayout.js.map +1 -0
  51. package/dist/components/msa/MSACanvas.js +6 -1
  52. package/dist/components/msa/MSACanvas.js.map +1 -1
  53. package/dist/components/msa/MSACanvasBlock.js +5 -1
  54. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  55. package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
  56. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  57. package/dist/components/msa/getVisibleLeaves.d.ts +6 -0
  58. package/dist/components/msa/getVisibleLeaves.js +9 -0
  59. package/dist/components/msa/getVisibleLeaves.js.map +1 -0
  60. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +2 -1
  61. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +5 -6
  62. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  63. package/dist/components/msa/renderMSABlock.d.ts +2 -1
  64. package/dist/components/msa/renderMSABlock.js +100 -88
  65. package/dist/components/msa/renderMSABlock.js.map +1 -1
  66. package/dist/components/msa/renderMSAMouseover.js +5 -4
  67. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  68. package/dist/components/msa/visibleColRange.d.ts +8 -0
  69. package/dist/components/msa/visibleColRange.js +10 -0
  70. package/dist/components/msa/visibleColRange.js.map +1 -0
  71. package/dist/components/renderCtx.d.ts +7 -0
  72. package/dist/components/renderCtx.js +2 -0
  73. package/dist/components/renderCtx.js.map +1 -0
  74. package/dist/components/tracks/renderTracksSvg.d.ts +6 -5
  75. package/dist/components/tracks/renderTracksSvg.js +13 -5
  76. package/dist/components/tracks/renderTracksSvg.js.map +1 -1
  77. package/dist/components/tree/TreeCanvas.js.map +1 -1
  78. package/dist/components/tree/TreeCanvasBlock.js +2 -10
  79. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  80. package/dist/components/tree/renderTreeCanvas.d.ts +5 -4
  81. package/dist/components/tree/renderTreeCanvas.js +18 -26
  82. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  83. package/dist/components/util.d.ts +0 -14
  84. package/dist/components/util.js +0 -58
  85. package/dist/components/util.js.map +1 -1
  86. package/dist/constants.d.ts +4 -0
  87. package/dist/constants.js +7 -0
  88. package/dist/constants.js.map +1 -1
  89. package/dist/flatToTree.js +6 -0
  90. package/dist/flatToTree.js.map +1 -1
  91. package/dist/hierarchy.d.ts +3 -1
  92. package/dist/hierarchy.js +142 -89
  93. package/dist/hierarchy.js.map +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.js +8 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/launchInterProScan.js +22 -9
  98. package/dist/launchInterProScan.js.map +1 -1
  99. package/dist/measureTextCanvas.js +2 -1
  100. package/dist/measureTextCanvas.js.map +1 -1
  101. package/dist/model.d.ts +234 -176
  102. package/dist/model.js +285 -259
  103. package/dist/model.js.map +1 -1
  104. package/dist/parseAsn1.js +8 -2
  105. package/dist/parseAsn1.js.map +1 -1
  106. package/dist/renderToSvg.d.ts +1 -1
  107. package/dist/renderToSvg.js +43 -46
  108. package/dist/renderToSvg.js.map +1 -1
  109. package/dist/rowCoordinateCalculations.d.ts +0 -9
  110. package/dist/rowCoordinateCalculations.js +0 -20
  111. package/dist/rowCoordinateCalculations.js.map +1 -1
  112. package/dist/setFontSize.d.ts +3 -0
  113. package/dist/setFontSize.js +14 -0
  114. package/dist/setFontSize.js.map +1 -0
  115. package/dist/useDevicePixelRatio.d.ts +1 -0
  116. package/dist/useDevicePixelRatio.js +27 -0
  117. package/dist/useDevicePixelRatio.js.map +1 -0
  118. package/dist/useWheelScroll.d.ts +3 -1
  119. package/dist/useWheelScroll.js +64 -22
  120. package/dist/useWheelScroll.js.map +1 -1
  121. package/dist/util.d.ts +5 -0
  122. package/dist/util.js +59 -1
  123. package/dist/util.js.map +1 -1
  124. package/dist/version.d.ts +1 -1
  125. package/dist/version.js +1 -1
  126. package/dist/webpack.js +0 -1
  127. package/dist/webpack.js.map +1 -1
  128. package/dist/wheelZoom.d.ts +4 -0
  129. package/dist/wheelZoom.js +43 -0
  130. package/dist/wheelZoom.js.map +1 -0
  131. package/package.json +5 -5
  132. package/src/calculateBlocks.ts +18 -51
  133. package/src/components/ConservationTrack.tsx +20 -45
  134. package/src/components/MSAView.tsx +10 -1
  135. package/src/components/ResizeHandles.tsx +101 -113
  136. package/src/components/TextTrack.tsx +31 -38
  137. package/src/components/Track.tsx +1 -1
  138. package/src/components/VerticalScrollbar.tsx +2 -2
  139. package/src/components/dialogs/ExportSVGDialog.tsx +27 -17
  140. package/src/components/dialogs/InterProScanDialog.tsx +6 -1
  141. package/src/components/dialogs/UserProvidedDomainsDialog.tsx +1 -2
  142. package/src/components/header/ColorSchemeMenu.tsx +1 -0
  143. package/src/components/header/FileMenu.tsx +3 -1
  144. package/src/components/header/Header.tsx +1 -1
  145. package/src/components/header/HeaderInfoArea.tsx +32 -7
  146. package/src/components/header/MSASettingsMenu.tsx +1 -0
  147. package/src/components/header/TreeSettingsMenu.tsx +1 -0
  148. package/src/components/header/ZoomControls.tsx +14 -1
  149. package/src/components/header/ZoomMenu.tsx +10 -0
  150. package/src/components/header/settingsMenuItems.ts +24 -8
  151. package/src/components/minimap/Minimap.tsx +6 -20
  152. package/src/components/minimap/MinimapSVG.tsx +10 -27
  153. package/src/components/minimap/minimapLayout.ts +17 -0
  154. package/src/components/msa/MSACanvas.tsx +9 -0
  155. package/src/components/msa/MSACanvasBlock.tsx +7 -1
  156. package/src/components/msa/MSAMouseoverCanvas.tsx +4 -3
  157. package/src/components/msa/getVisibleLeaves.ts +21 -0
  158. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +9 -9
  159. package/src/components/msa/renderMSABlock.ts +123 -125
  160. package/src/components/msa/renderMSAMouseover.ts +5 -4
  161. package/src/components/msa/visibleColRange.ts +17 -0
  162. package/src/components/renderCtx.ts +29 -0
  163. package/src/components/tracks/renderTracksSvg.ts +20 -10
  164. package/src/components/tree/TreeCanvas.tsx +3 -1
  165. package/src/components/tree/TreeCanvasBlock.tsx +2 -12
  166. package/src/components/tree/renderTreeCanvas.ts +27 -30
  167. package/src/components/util.ts +0 -81
  168. package/src/constants.ts +8 -0
  169. package/src/flatToTree.test.ts +30 -0
  170. package/src/flatToTree.ts +10 -1
  171. package/src/hierarchy.test.ts +53 -1
  172. package/src/hierarchy.ts +153 -100
  173. package/src/index.ts +8 -0
  174. package/src/launchInterProScan.ts +33 -11
  175. package/src/measureTextCanvas.ts +3 -1
  176. package/src/model.ts +359 -306
  177. package/src/parseAsn1.test.ts +6 -0
  178. package/src/parseAsn1.ts +11 -3
  179. package/src/renderToSvg.tsx +99 -95
  180. package/src/rowCoordinateCalculations.test.ts +0 -51
  181. package/src/rowCoordinateCalculations.ts +0 -23
  182. package/src/setFontSize.test.ts +33 -0
  183. package/src/setFontSize.ts +20 -0
  184. package/src/useDevicePixelRatio.ts +29 -0
  185. package/src/useWheelScroll.ts +79 -21
  186. package/src/util.ts +60 -1
  187. package/src/version.ts +1 -1
  188. package/src/webpack.ts +0 -1
  189. package/src/wheelZoom.test.ts +46 -0
  190. package/src/wheelZoom.ts +47 -0
@@ -1,8 +1,14 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
- export function useWheelScroll({ ref, onScrollX, onScrollY, }) {
2
+ import { SCROLL_ZOOM_DIVISOR, getZoomNormalizer, normalizeWheelDelta, zoomFactorFromAccum, } from "./wheelZoom.js";
3
+ export function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, scrollZoom, }) {
3
4
  const scheduled = useRef(false);
5
+ const zoomScheduled = useRef(false);
4
6
  const deltaX = useRef(0);
5
7
  const deltaY = useRef(0);
8
+ const zoomAccum = useRef(0);
9
+ const zoomX = useRef(0);
10
+ const zoomY = useRef(0);
11
+ const lastZoomTime = useRef(null);
6
12
  const prevX = useRef(0);
7
13
  const prevY = useRef(0);
8
14
  const [mouseDragging, setMouseDragging] = useState(false);
@@ -12,34 +18,70 @@ export function useWheelScroll({ ref, onScrollX, onScrollY, }) {
12
18
  return;
13
19
  }
14
20
  function onWheel(event) {
15
- if (onScrollX) {
16
- deltaX.current += event.deltaX;
17
- }
18
- if (onScrollY) {
19
- deltaY.current += event.deltaY;
21
+ // ctrlKey is also set by trackpad pinch gestures on all platforms. when
22
+ // scrollZoom is on, a plain vertical-dominant wheel zooms too; holding
23
+ // shift is the escape hatch to pan instead.
24
+ const isCtrlZoom = event.ctrlKey || event.metaKey;
25
+ const isScrollZoom = scrollZoom &&
26
+ !event.shiftKey &&
27
+ Math.abs(event.deltaY) >= Math.abs(event.deltaX);
28
+ if (onZoom && (isCtrlZoom || isScrollZoom)) {
29
+ const rect = curr.getBoundingClientRect();
30
+ // normalize away deltaMode (line/page), then divide by an adaptive
31
+ // factor so fine pinches and coarse notches feel consistent
32
+ const dY = normalizeWheelDelta(event.deltaY, event.deltaMode);
33
+ const divisor = isCtrlZoom ? getZoomNormalizer(dY) : SCROLL_ZOOM_DIVISOR;
34
+ zoomAccum.current += dY / divisor;
35
+ zoomX.current = event.clientX - rect.left;
36
+ zoomY.current = event.clientY - rect.top;
37
+ if (!zoomScheduled.current) {
38
+ zoomScheduled.current = true;
39
+ requestAnimationFrame(now => {
40
+ const elapsed = lastZoomTime.current === null ? 16.67 : now - lastZoomTime.current;
41
+ lastZoomTime.current = now;
42
+ onZoom(zoomFactorFromAccum(zoomAccum.current, Math.min(100, elapsed)), zoomX.current, zoomY.current);
43
+ zoomAccum.current = 0;
44
+ zoomScheduled.current = false;
45
+ });
46
+ }
47
+ event.preventDefault();
48
+ event.stopPropagation();
49
+ return;
20
50
  }
21
- if (!scheduled.current) {
22
- scheduled.current = true;
23
- requestAnimationFrame(() => {
24
- if (onScrollX) {
25
- onScrollX(-deltaX.current);
26
- deltaX.current = 0;
27
- }
28
- if (onScrollY) {
29
- onScrollY(-deltaY.current);
30
- deltaY.current = 0;
31
- }
32
- scheduled.current = false;
33
- });
51
+ // only swallow the wheel event on an axis we actually handle, otherwise a
52
+ // vertical wheel over an x-only scroller (e.g. a Track) blocks page scroll
53
+ const consumeX = !!onScrollX && event.deltaX !== 0;
54
+ const consumeY = !!onScrollY && event.deltaY !== 0;
55
+ if (consumeX || consumeY) {
56
+ if (onScrollX) {
57
+ deltaX.current += event.deltaX;
58
+ }
59
+ if (onScrollY) {
60
+ deltaY.current += event.deltaY;
61
+ }
62
+ if (!scheduled.current) {
63
+ scheduled.current = true;
64
+ requestAnimationFrame(() => {
65
+ if (onScrollX) {
66
+ onScrollX(-deltaX.current);
67
+ deltaX.current = 0;
68
+ }
69
+ if (onScrollY) {
70
+ onScrollY(-deltaY.current);
71
+ deltaY.current = 0;
72
+ }
73
+ scheduled.current = false;
74
+ });
75
+ }
76
+ event.preventDefault();
77
+ event.stopPropagation();
34
78
  }
35
- event.preventDefault();
36
- event.stopPropagation();
37
79
  }
38
80
  curr.addEventListener('wheel', onWheel, { passive: false });
39
81
  return () => {
40
82
  curr.removeEventListener('wheel', onWheel);
41
83
  };
42
- }, [ref, onScrollX, onScrollY]);
84
+ }, [ref, onScrollX, onScrollY, onZoom, scrollZoom]);
43
85
  useEffect(() => {
44
86
  if (!mouseDragging) {
45
87
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"useWheelScroll.js","sourceRoot":"","sources":["../src/useWheelScroll.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useWheelScroll.js","sourceRoot":"","sources":["../src/useWheelScroll.ts"],"names":[],"mappings":"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"}
package/dist/util.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { Theme } from '@mui/material';
2
+ export declare function adjustColorForContrast(color: string, bg: string): string;
2
3
  export declare function transform<T>(obj: Record<string, T>, cb: (arg0: [string, T]) => [string, T]): {
3
4
  [k: string]: T;
4
5
  };
@@ -6,6 +7,10 @@ export declare function colorContrast(colorScheme: Record<string, string>, theme
6
7
  [k: string]: string;
7
8
  };
8
9
  export declare function skipBlanks(blanks: number[], str: string): string;
10
+ export declare function computeRowInsertions(blanks: number[], seq: string): {
11
+ pos: number;
12
+ letters: string;
13
+ }[];
9
14
  export declare function len(a: {
10
15
  end: number;
11
16
  start: number;
package/dist/util.js CHANGED
@@ -1,6 +1,28 @@
1
1
  import { colord, extend } from 'colord';
2
+ import a11yPlugin from 'colord/plugins/a11y';
2
3
  import namesPlugin from 'colord/plugins/names';
3
- extend([namesPlugin]);
4
+ extend([namesPlugin, a11yPlugin]);
5
+ const contrastAdjustCache = new Map();
6
+ // Adjusts a background-tile color until it meets WCAG AA (4.5:1) contrast
7
+ // against `bg`, so it can be used as letter text in letter-color mode.
8
+ // Darkens on light backgrounds, lightens on dark backgrounds.
9
+ export function adjustColorForContrast(color, bg) {
10
+ const cacheKey = `${color}|${bg}`;
11
+ const cached = contrastAdjustCache.get(cacheKey);
12
+ if (cached !== undefined) {
13
+ return cached;
14
+ }
15
+ let c = colord(color);
16
+ if (!c.isReadable(bg)) {
17
+ const bgIsDark = colord(bg).luminance() < 0.5;
18
+ for (let i = 0; i < 40 && !c.isReadable(bg); i++) {
19
+ c = bgIsDark ? c.lighten(0.05) : c.darken(0.05);
20
+ }
21
+ }
22
+ const result = c.toHex();
23
+ contrastAdjustCache.set(cacheKey, result);
24
+ return result;
25
+ }
4
26
  export function transform(obj, cb) {
5
27
  return Object.fromEntries(Object.entries(obj).map(cb));
6
28
  }
@@ -27,6 +49,42 @@ export function skipBlanks(blanks, str) {
27
49
  }
28
50
  return chunks.join('');
29
51
  }
52
+ export function computeRowInsertions(blanks, seq) {
53
+ const insertions = [];
54
+ const blanksLen = blanks.length;
55
+ let displayPos = 0;
56
+ let blankIdx = 0;
57
+ let currentInsertPos = -1;
58
+ let letterChars = [];
59
+ for (let i = 0; i < seq.length; i++) {
60
+ if (blankIdx < blanksLen && blanks[blankIdx] === i) {
61
+ // bit trick: (code - 45) >>> 0 <= 1 checks for '-' (45) or '.' (46)
62
+ if (!((seq.charCodeAt(i) - 45) >>> 0 <= 1)) {
63
+ if (currentInsertPos === displayPos) {
64
+ letterChars.push(seq[i]);
65
+ }
66
+ else {
67
+ if (letterChars.length > 0) {
68
+ insertions.push({
69
+ pos: currentInsertPos,
70
+ letters: letterChars.join(''),
71
+ });
72
+ }
73
+ currentInsertPos = displayPos;
74
+ letterChars = [seq[i]];
75
+ }
76
+ }
77
+ blankIdx++;
78
+ }
79
+ else {
80
+ displayPos++;
81
+ }
82
+ }
83
+ if (letterChars.length > 0) {
84
+ insertions.push({ pos: currentInsertPos, letters: letterChars.join('') });
85
+ }
86
+ return insertions;
87
+ }
30
88
  export function len(a) {
31
89
  return a.end - a.start;
32
90
  }
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,WAAW,MAAM,sBAAsB,CAAA;AAI9C,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,CAAA;AAErB,MAAM,UAAU,SAAS,CACvB,GAAsB,EACtB,EAAsC;IAEtC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,WAAmC,EACnC,KAAY;IAEZ,OAAO,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QACjD,MAAM;QACN,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;KACrD,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAgB,EAAE,GAAW;IACtD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAA;IACjB,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,QAAQ,IAAI,MAAM,EAAE,CAAC;QAC9B,IAAI,QAAQ,GAAG,OAAO,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;QAC3C,CAAC;QACD,OAAO,GAAG,QAAQ,GAAG,CAAC,CAAA;IACxB,CAAC;IACD,IAAI,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,CAAiC;IACnD,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAA;AACxB,CAAC;AAED,8CAA8C;AAC9C,oCAAoC;AACpC,MAAM,UAAU,OAAO,CAAC,CAAU;IAChC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAA;AAC/B,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.1.1";
1
+ export declare const version = "5.2.1";
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '5.1.1';
1
+ export const version = '5.2.1';
2
2
  //# sourceMappingURL=version.js.map
package/dist/webpack.js CHANGED
@@ -2,6 +2,5 @@ import * as React from 'react';
2
2
  export { default as MSAView } from "./components/Loading.js";
3
3
  export { default as MSAModelF } from "./model.js";
4
4
  export * from 'react-dom/client';
5
- // eslint-disable-next-line unicorn/prefer-export-from
6
5
  export { React };
7
6
  //# sourceMappingURL=webpack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webpack.js","sourceRoot":"","sources":["../src/webpack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAA0B,CAAA;AAC7D,OAAO,EAAqB,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA;AAEpE,cAAc,kBAAkB,CAAA;AAEhC,sDAAsD;AACtD,OAAO,EAAE,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"webpack.js","sourceRoot":"","sources":["../src/webpack.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,yBAA0B,CAAA;AAC7D,OAAO,EAAqB,OAAO,IAAI,SAAS,EAAE,MAAM,YAAY,CAAA;AAEpE,cAAc,kBAAkB,CAAA;AAEhC,OAAO,EAAE,KAAK,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ export declare const SCROLL_ZOOM_DIVISOR = 500;
2
+ export declare function normalizeWheelDelta(delta: number, mode: number): number;
3
+ export declare function getZoomNormalizer(deltaY: number): 500 | 25 | 150 | 75;
4
+ export declare function zoomFactorFromAccum(zoomAccum: number, elapsedMs: number): number;
@@ -0,0 +1,43 @@
1
+ // Wheel / trackpad-pinch delta handling, adapted from @jbrowse/core's
2
+ // util/wheelZoom (not yet in our pinned @jbrowse/core). Turns raw wheel deltas
3
+ // into a per-frame zoom factor that feels consistent across fine trackpad
4
+ // pinches and coarse mouse notches.
5
+ // Fixed divisor for plain-wheel scroll-zoom mode, where deltas are big notches.
6
+ export const SCROLL_ZOOM_DIVISOR = 500;
7
+ // Cap the zoom change per millisecond so a burst of momentum-scroll events
8
+ // coalesced into one frame can't jump the zoom level (0.2 per ~60fps frame).
9
+ const MAX_ZOOM_RATE_PER_MS = 0.2 / 16.67;
10
+ // Convert a wheel delta to pixels regardless of the browser's deltaMode; some
11
+ // browsers/mice report lines or pages instead of pixels.
12
+ export function normalizeWheelDelta(delta, mode) {
13
+ if (mode === 1) {
14
+ return delta * 16; // DOM_DELTA_LINE
15
+ }
16
+ if (mode === 2) {
17
+ return delta * 100; // DOM_DELTA_PAGE
18
+ }
19
+ return delta; // DOM_DELTA_PIXEL
20
+ }
21
+ // Adaptive divisor: tiny pinch deltas zoom in larger steps, big mouse notches
22
+ // in finer steps, so a trackpad pinch and a mouse wheel feel similar.
23
+ export function getZoomNormalizer(deltaY) {
24
+ const abs = Math.abs(deltaY);
25
+ if (abs < 6) {
26
+ return 25;
27
+ }
28
+ if (abs > 150) {
29
+ return 500;
30
+ }
31
+ if (abs > 30) {
32
+ return 150;
33
+ }
34
+ return 75;
35
+ }
36
+ // Turn accumulated, normalized zoom intent into a colWidth/rowHeight multiplier.
37
+ // Positive accum (wheel toward user) zooms out (factor < 1); negative zooms in.
38
+ export function zoomFactorFromAccum(zoomAccum, elapsedMs) {
39
+ const max = MAX_ZOOM_RATE_PER_MS * elapsedMs;
40
+ const d = Math.max(-max, Math.min(max, zoomAccum));
41
+ return d > 0 ? 1 / (1 + d) : 1 - d;
42
+ }
43
+ //# sourceMappingURL=wheelZoom.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wheelZoom.js","sourceRoot":"","sources":["../src/wheelZoom.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,+EAA+E;AAC/E,0EAA0E;AAC1E,oCAAoC;AAEpC,gFAAgF;AAChF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;AAEtC,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,oBAAoB,GAAG,GAAG,GAAG,KAAK,CAAA;AAExC,8EAA8E;AAC9E,yDAAyD;AACzD,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,IAAY;IAC7D,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,OAAO,KAAK,GAAG,EAAE,CAAA,CAAC,iBAAiB;IACrC,CAAC;IACD,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;QACf,OAAO,KAAK,GAAG,GAAG,CAAA,CAAC,iBAAiB;IACtC,CAAC;IACD,OAAO,KAAK,CAAA,CAAC,kBAAkB;AACjC,CAAC;AAED,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAC5B,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACZ,OAAO,EAAE,CAAA;IACX,CAAC;IACD,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACd,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,GAAG,GAAG,EAAE,EAAE,CAAC;QACb,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,iFAAiF;AACjF,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CAAC,SAAiB,EAAE,SAAiB;IACtE,MAAM,GAAG,GAAG,oBAAoB,GAAG,SAAS,CAAA;IAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAA;IAClD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACpC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-msaview",
3
3
  "author": "Colin",
4
- "version": "5.1.1",
4
+ "version": "5.2.1",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "repository": {
@@ -35,15 +35,15 @@
35
35
  "react-dom": ">=16.8.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/node": "^25.9.1"
38
+ "@types/node": "^25.9.2"
39
39
  },
40
40
  "dependencies": {
41
41
  "@mui/icons-material": "^7.3.11",
42
42
  "@mui/material": "^7.3.11",
43
43
  "colord": "^2.9.3",
44
- "flatbush": "^4.5.1",
45
- "@jbrowse/svgcanvas": "5.1.1",
46
- "msa-parsers": "5.1.1"
44
+ "flatbush": "^4.6.1",
45
+ "@jbrowse/svgcanvas": "5.2.1",
46
+ "msa-parsers": "5.2.1"
47
47
  },
48
48
  "scripts": {
49
49
  "clean": "rimraf dist bundle",
@@ -1,58 +1,25 @@
1
- export function blocksY({
2
- mapHeight,
1
+ // Returns the block offsets (in pixels) needed to cover the viewport along one
2
+ // axis. mapSize/viewportPos/viewportSize are all in pixels. The clamp pins the
3
+ // block set to the content edge so an over-scroll past the end still fills the
4
+ // viewport rather than leaving a gap.
5
+ export function calculateBlocks({
6
+ mapSize,
3
7
  blockSize,
4
- viewportY,
5
- viewportHeight,
8
+ viewportPos,
9
+ viewportSize,
6
10
  }: {
7
- mapHeight: number
11
+ mapSize: number
8
12
  blockSize: number
9
- viewportY: number
10
- viewportHeight: number
13
+ viewportPos: number
14
+ viewportSize: number
11
15
  }) {
12
- const clampedViewportY = Math.max(
13
- 0,
14
- Math.min(viewportY, mapHeight * blockSize - viewportHeight),
15
- )
16
+ const clamped = Math.max(0, Math.min(viewportPos, mapSize - viewportSize))
17
+ const minTile = Math.floor(clamped / blockSize)
18
+ const maxTile = Math.floor((clamped + viewportSize - 1) / blockSize)
16
19
 
17
- // Calculate visible tile ranges
18
- const minTileY = Math.floor(clampedViewportY / blockSize)
19
- const maxTileY = Math.floor(
20
- (clampedViewportY + viewportHeight - 1) / blockSize,
21
- )
22
-
23
- // Generate list of visible tiles
24
- const blocksY = []
25
- for (let tileY = minTileY; tileY <= maxTileY; tileY++) {
26
- blocksY.push(tileY * blockSize)
20
+ const blocks = []
21
+ for (let tile = minTile; tile <= maxTile; tile++) {
22
+ blocks.push(tile * blockSize)
27
23
  }
28
-
29
- return blocksY
30
- }
31
-
32
- export function blocksX({
33
- mapWidth,
34
- blockSize,
35
- viewportX,
36
- viewportWidth,
37
- }: {
38
- mapWidth: number
39
- blockSize: number
40
- viewportX: number
41
- viewportWidth: number
42
- }) {
43
- const clampedViewportX = Math.max(
44
- 0,
45
- Math.min(viewportX, mapWidth - viewportWidth),
46
- )
47
-
48
- const minTileX = Math.floor(clampedViewportX / blockSize)
49
- const maxTileX = Math.floor(
50
- (clampedViewportX + viewportWidth - 1) / blockSize,
51
- )
52
- const blocksX = []
53
- for (let tileX = minTileX; tileX <= maxTileX; tileX++) {
54
- blocksX.push(tileX * blockSize)
55
- }
56
-
57
- return blocksX
24
+ return blocks
58
25
  }
@@ -1,8 +1,9 @@
1
1
  import React, { useEffect, useRef } from 'react'
2
2
 
3
- import { ResizeHandle } from '@jbrowse/core/ui'
3
+ import { autorun } from 'mobx'
4
4
  import { observer } from 'mobx-react'
5
5
 
6
+ import { ConservationTrackResizeHandle } from './ResizeHandles.tsx'
6
7
  import { drawConservationBars } from './tracks/renderTracksSvg.ts'
7
8
 
8
9
  import type { MsaViewModel } from '../model.ts'
@@ -17,42 +18,32 @@ const ConservationBlock = observer(function ({
17
18
  offsetX: number
18
19
  trackHeight: number
19
20
  }) {
20
- const { blockSize, scrollX, colWidth, highResScaleFactor, conservation } =
21
- model
21
+ const { blockSize, scrollX, highResScaleFactor } = model
22
22
 
23
23
  const ref = useRef<HTMLCanvasElement>(null)
24
24
 
25
25
  useEffect(() => {
26
- if (!ref.current) {
27
- return
28
- }
29
-
30
- const ctx = ref.current.getContext('2d')
26
+ const ctx = ref.current?.getContext('2d')
31
27
  if (!ctx) {
32
28
  return
33
29
  }
30
+ return autorun(() => {
31
+ const { blockSize, colWidth, highResScaleFactor, conservation } = model
32
+ ctx.resetTransform()
33
+ ctx.scale(highResScaleFactor, highResScaleFactor)
34
+ ctx.clearRect(0, 0, blockSize, trackHeight)
35
+ ctx.translate(-offsetX, 0)
34
36
 
35
- ctx.resetTransform()
36
- ctx.scale(highResScaleFactor, highResScaleFactor)
37
- ctx.clearRect(0, 0, blockSize, trackHeight)
38
- ctx.translate(-offsetX, 0)
39
-
40
- drawConservationBars({
41
- ctx,
42
- conservation,
43
- colWidth,
44
- trackHeight,
45
- offsetX,
46
- blockSize,
37
+ drawConservationBars({
38
+ ctx,
39
+ conservation,
40
+ colWidth,
41
+ trackHeight,
42
+ offsetX,
43
+ blockSize,
44
+ })
47
45
  })
48
- }, [
49
- blockSize,
50
- colWidth,
51
- trackHeight,
52
- offsetX,
53
- highResScaleFactor,
54
- conservation,
55
- ])
46
+ }, [model, offsetX, trackHeight])
56
47
 
57
48
  return (
58
49
  <canvas
@@ -96,23 +87,7 @@ const ConservationTrack = observer(function ({
96
87
  trackHeight={trackHeight}
97
88
  />
98
89
  ))}
99
- <ResizeHandle
100
- onDrag={delta => {
101
- model.setConservationTrackHeight(
102
- Math.max(10, model.conservationTrackHeight + delta),
103
- )
104
- return delta
105
- }}
106
- style={{
107
- position: 'absolute',
108
- bottom: 0,
109
- left: 0,
110
- height: 4,
111
- width: '100%',
112
- zIndex: 1,
113
- background: 'rgba(200,200,200,0.5)',
114
- }}
115
- />
90
+ <ConservationTrackResizeHandle model={model} />
116
91
  </div>
117
92
  )
118
93
  })
@@ -1,7 +1,8 @@
1
- import React, { Suspense } from 'react'
1
+ import React, { Suspense, useEffect } from 'react'
2
2
 
3
3
  import { observer } from 'mobx-react'
4
4
 
5
+ import { useDevicePixelRatio } from '../useDevicePixelRatio.ts'
5
6
  import {
6
7
  HorizontalResizeHandle,
7
8
  VerticalResizeHandle,
@@ -128,6 +129,14 @@ const View = observer(function ({ model }: { model: MsaViewModel }) {
128
129
 
129
130
  const MSAView = observer(function ({ model }: { model: MsaViewModel }) {
130
131
  const { height, viewInitialized, DialogComponent, DialogProps } = model
132
+
133
+ // mirror the live device pixel ratio into the model so canvas backing stores
134
+ // re-scale when the window moves between monitors or the browser zooms
135
+ const devicePixelRatio = useDevicePixelRatio()
136
+ useEffect(() => {
137
+ model.setHighResScaleFactor(devicePixelRatio)
138
+ }, [model, devicePixelRatio])
139
+
131
140
  return (
132
141
  <div>
133
142
  {viewInitialized ? (