@genome-spy/core 0.62.2 → 0.63.0

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 (30) hide show
  1. package/dist/bundle/index.es.js +4052 -3992
  2. package/dist/bundle/index.js +97 -97
  3. package/dist/src/genomeSpy.d.ts +11 -0
  4. package/dist/src/genomeSpy.d.ts.map +1 -1
  5. package/dist/src/genomeSpy.js +98 -20
  6. package/dist/src/gl/includes/common.glsl.js +1 -1
  7. package/dist/src/gl/webGLHelper.d.ts +18 -14
  8. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  9. package/dist/src/gl/webGLHelper.js +58 -65
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/index.js +1 -0
  12. package/dist/src/marks/mark.d.ts +6 -1
  13. package/dist/src/marks/mark.d.ts.map +1 -1
  14. package/dist/src/marks/mark.js +10 -16
  15. package/dist/src/marks/rect.vertex.glsl.js +1 -1
  16. package/dist/src/marks/text.d.ts.map +1 -1
  17. package/dist/src/marks/text.js +7 -15
  18. package/dist/src/marks/text.vertex.glsl.js +1 -1
  19. package/dist/src/types/embedApi.d.ts +16 -0
  20. package/dist/src/types/viewContext.d.ts +0 -2
  21. package/dist/src/view/gridView/gridView.js +1 -1
  22. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts +32 -17
  23. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
  24. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +85 -39
  25. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
  26. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +5 -1
  27. package/dist/src/view/renderingContext/viewRenderingContext.d.ts +1 -0
  28. package/dist/src/view/renderingContext/viewRenderingContext.d.ts.map +1 -1
  29. package/dist/src/view/renderingContext/viewRenderingContext.js +4 -0
  30. package/package.json +2 -2
@@ -84,6 +84,7 @@ export default class GenomeSpy {
84
84
  _inputBindingContainer: HTMLElement;
85
85
  /** @type {Point} */
86
86
  _mouseDownCoords: Point;
87
+ dpr: number;
87
88
  /**
88
89
  *
89
90
  * @param {(name: string) => any[]} provider
@@ -141,6 +142,16 @@ export default class GenomeSpy {
141
142
  * @template T
142
143
  */
143
144
  updateTooltip<T>(datum: T, converter?: (arg0: T) => Promise<string | HTMLElement | import("lit").TemplateResult>): void;
145
+ /**
146
+ * Returns a PNG data URL of the current canvas.
147
+ *
148
+ * @param {number} [logicalWidth] defaults to canvas width
149
+ * @param {number} [logicalHeight] defaults to canvas height
150
+ * @param {number} [devicePixelRatio] defaults to window.devicePixelRatio
151
+ * @param {string} [clearColor] null for transparent
152
+ * @returns A PNG data Url
153
+ */
154
+ exportCanvas(logicalWidth?: number, logicalHeight?: number, devicePixelRatio?: number, clearColor?: string): string;
144
155
  computeLayout(): void;
145
156
  renderAll(): void;
146
157
  renderPickingFramebuffer(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"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"}
@@ -13,7 +13,10 @@ import {
13
13
  } from "./view/viewUtils.js";
14
14
  import UnitView from "./view/unitView.js";
15
15
 
16
- import WebGLHelper from "./gl/webGLHelper.js";
16
+ import WebGLHelper, {
17
+ framebufferToDataUrl,
18
+ readPickingPixel,
19
+ } from "./gl/webGLHelper.js";
17
20
  import Rectangle from "./view/layout/rectangle.js";
18
21
  import BufferedViewRenderingContext from "./view/renderingContext/bufferedViewRenderingContext.js";
19
22
  import CompositeViewRenderingContext from "./view/renderingContext/compositeViewRenderingContext.js";
@@ -35,6 +38,7 @@ import { VIEW_ROOT_NAME, ViewFactory } from "./view/viewFactory.js";
35
38
  import { reconfigureScales } from "./view/scaleResolution.js";
36
39
  import createBindingInputs from "./utils/inputBinding.js";
37
40
  import { isStillZooming } from "./view/zoom.js";
41
+ import { createFramebufferInfo } from "twgl.js";
38
42
 
39
43
  /**
40
44
  * Events that are broadcasted to all views.
@@ -148,6 +152,8 @@ export default class GenomeSpy {
148
152
 
149
153
  /** @type {Point} */
150
154
  this._mouseDownCoords = undefined;
155
+
156
+ this.dpr = window.devicePixelRatio;
151
157
  }
152
158
 
153
159
  get #canvasWrapper() {
@@ -307,12 +313,13 @@ export default class GenomeSpy {
307
313
  #setupDpr() {
308
314
  const dprSetter = this.viewRoot.paramMediator.allocateSetter(
309
315
  "devicePixelRatio",
310
- window.devicePixelRatio
316
+ this.dpr
311
317
  );
312
318
 
313
319
  const resizeCallback = () => {
314
320
  this._glHelper.invalidateSize();
315
- dprSetter(window.devicePixelRatio);
321
+ this.dpr = window.devicePixelRatio;
322
+ dprSetter(this.dpr);
316
323
  this.computeLayout();
317
324
  // Render immediately, without RAF
318
325
  this.renderAll();
@@ -368,7 +375,6 @@ export default class GenomeSpy {
368
375
  this.viewRoot
369
376
  ? calculateCanvasSize(this.viewRoot)
370
377
  : { width: undefined, height: undefined },
371
- this.spec.background,
372
378
  { powerPreference: this.options.powerPreference ?? "default" }
373
379
  );
374
380
 
@@ -444,10 +450,6 @@ export default class GenomeSpy {
444
450
  genomeStore: this.genomeStore,
445
451
  fontManager: new BmFontManager(this._glHelper),
446
452
 
447
- get devicePixelRatio() {
448
- return self._glHelper.dpr;
449
- },
450
-
451
453
  requestLayoutReflow: () => {
452
454
  // placeholder
453
455
  },
@@ -877,13 +879,15 @@ export default class GenomeSpy {
877
879
  * @param {number} y
878
880
  */
879
881
  _handlePicking(x, y) {
880
- const pixelValue = this._glHelper.readPickingPixel(x, y);
882
+ const dpr = this.dpr;
883
+ const pp = readPickingPixel(
884
+ this._glHelper.gl,
885
+ this._glHelper._pickingBufferInfo,
886
+ x * dpr,
887
+ y * dpr
888
+ );
881
889
 
882
- const uniqueId =
883
- pixelValue[0] |
884
- (pixelValue[1] << 8) |
885
- (pixelValue[2] << 16) |
886
- (pixelValue[3] << 24);
890
+ const uniqueId = pp[0] | (pp[1] << 8) | (pp[2] << 16) | (pp[3] << 24);
887
891
 
888
892
  if (uniqueId == 0) {
889
893
  this._currentHover = null;
@@ -964,6 +968,72 @@ export default class GenomeSpy {
964
968
  }
965
969
  }
966
970
 
971
+ /**
972
+ * Returns a PNG data URL of the current canvas.
973
+ *
974
+ * @param {number} [logicalWidth] defaults to canvas width
975
+ * @param {number} [logicalHeight] defaults to canvas height
976
+ * @param {number} [devicePixelRatio] defaults to window.devicePixelRatio
977
+ * @param {string} [clearColor] null for transparent
978
+ * @returns A PNG data Url
979
+ */
980
+ exportCanvas(
981
+ logicalWidth,
982
+ logicalHeight,
983
+ devicePixelRatio,
984
+ clearColor = "white"
985
+ ) {
986
+ const helper = this._glHelper;
987
+
988
+ logicalWidth ??= helper.getLogicalCanvasSize().width;
989
+ logicalHeight ??= helper.getLogicalCanvasSize().height;
990
+ devicePixelRatio ??= window.devicePixelRatio ?? 1;
991
+
992
+ const gl = helper.gl;
993
+
994
+ const width = Math.floor(logicalWidth * devicePixelRatio);
995
+ const height = Math.floor(logicalHeight * devicePixelRatio);
996
+
997
+ const framebufferInfo = createFramebufferInfo(
998
+ gl,
999
+ [
1000
+ {
1001
+ format: gl.RGBA,
1002
+ type: gl.UNSIGNED_BYTE,
1003
+ minMag: gl.LINEAR,
1004
+ wrap: gl.CLAMP_TO_EDGE,
1005
+ },
1006
+ ],
1007
+ width,
1008
+ height
1009
+ );
1010
+
1011
+ const renderingContext = new BufferedViewRenderingContext(
1012
+ { picking: false },
1013
+ {
1014
+ webGLHelper: this._glHelper,
1015
+ canvasSize: { width: logicalWidth, height: logicalHeight },
1016
+ devicePixelRatio,
1017
+ clearColor,
1018
+ framebufferInfo,
1019
+ }
1020
+ );
1021
+
1022
+ this.viewRoot.render(
1023
+ renderingContext,
1024
+ Rectangle.create(0, 0, logicalWidth, logicalHeight)
1025
+ );
1026
+ renderingContext.render();
1027
+
1028
+ const pngUrl = framebufferToDataUrl(gl, framebufferInfo, "image/png");
1029
+
1030
+ // Clean up
1031
+ this.computeLayout();
1032
+ this.renderAll();
1033
+
1034
+ return pngUrl;
1035
+ }
1036
+
967
1037
  computeLayout() {
968
1038
  const root = this.viewRoot;
969
1039
  if (!root) {
@@ -982,17 +1052,25 @@ export default class GenomeSpy {
982
1052
  return;
983
1053
  }
984
1054
 
1055
+ const commonOptions = {
1056
+ webGLHelper: this._glHelper,
1057
+ canvasSize,
1058
+ devicePixelRatio: window.devicePixelRatio ?? 1,
1059
+ };
1060
+
985
1061
  this._renderingContext = new BufferedViewRenderingContext(
1062
+ { picking: false },
986
1063
  {
987
- picking: false,
988
- },
989
- this._glHelper
1064
+ ...commonOptions,
1065
+ clearColor: this.spec.background,
1066
+ }
990
1067
  );
991
1068
  this._pickingContext = new BufferedViewRenderingContext(
1069
+ { picking: true },
992
1070
  {
993
- picking: true,
994
- },
995
- this._glHelper
1071
+ ...commonOptions,
1072
+ framebufferInfo: this._glHelper._pickingBufferInfo,
1073
+ }
996
1074
  );
997
1075
 
998
1076
  root.render(
@@ -1,2 +1,2 @@
1
- const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool isEmptyBinarySearchTexture(highp usampler2D s){return textureSize(s,0).x==1&&texelFetch(s,ivec2(0,0),0).r==0u;}bool binarySearchTexture(highp usampler2D s,uint value){int texSize=textureSize(s,0).x;int left=0;int right=texSize-1;while(left<=right){int mid=left+(right-left)/2;uint midValue=texelFetch(s,ivec2(mid,0),0).r;if(midValue==value){return true;}if(midValue<value){left=mid+1;}else{right=mid-1;}}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,vec4 background,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : background,distanceToRatio(sd));}else{return mix(background,fill,distanceToRatio(-d));}}";
1
+ const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool isEmptyBinarySearchTexture(highp usampler2D s){return textureSize(s,0).x==1&&texelFetch(s,ivec2(0,0),0).r==0u;}bool binarySearchTexture(highp usampler2D s,uint value){int texSize=textureSize(s,0).x;if(texSize==1&&texelFetch(s,ivec2(0,0),0).r==0u){return false;}int left=0;int right=texSize-1;while(left<=right){int mid=left+(right-left)/2;uint midValue=texelFetch(s,ivec2(mid,0),0).r;if(midValue==value){return true;}if(midValue<value){left=mid+1;}else{right=mid-1;}}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,vec4 background,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : background,distanceToRatio(sd));}else{return mix(background,fill,distanceToRatio(-d));}}";
2
2
  export default shader;
@@ -17,6 +17,21 @@ export function createProgram(gl: WebGL2RenderingContext, vertexShader: WebGLSha
17
17
  * @param {WebGLTexture} [texture]
18
18
  */
19
19
  export function createOrUpdateTexture(gl: WebGLRenderingContext, options: Omit<import("twgl.js").TextureOptions, "src">, src: number[] | ArrayBufferView, texture?: WebGLTexture): WebGLTexture;
20
+ /**
21
+ *
22
+ * @param {WebGL2RenderingContext} gl
23
+ * @param {import("twgl.js").FramebufferInfo} framebufferInfo
24
+ * @param {number} x
25
+ * @param {number} y
26
+ */
27
+ export function readPickingPixel(gl: WebGL2RenderingContext, framebufferInfo: import("twgl.js").FramebufferInfo, x: number, y: number): Uint8Array<ArrayBuffer>;
28
+ /**
29
+ *
30
+ * @param {WebGL2RenderingContext} gl
31
+ * @param {import("twgl.js").FramebufferInfo} framebufferInfo
32
+ * @param {string} [type]
33
+ */
34
+ export function framebufferToDataUrl(gl: WebGL2RenderingContext, framebufferInfo: import("twgl.js").FramebufferInfo, type?: string): string;
20
35
  export default class WebGLHelper {
21
36
  /**
22
37
  *
@@ -24,13 +39,12 @@ export default class WebGLHelper {
24
39
  * @param {() => {width: number, height: number}} [sizeSource]
25
40
  * A function that returns the content size. If a dimension is undefined,
26
41
  * the canvas fills the container, otherwise the canvas is adjusted to the content size.
27
- * @param {string} [clearColor]
28
42
  * @param {WebGLContextAttributes} [webglContextAttributes]
29
43
  */
30
44
  constructor(container: HTMLElement, sizeSource?: () => {
31
45
  width: number;
32
46
  height: number;
33
- }, clearColor?: string, webglContextAttributes?: WebGLContextAttributes);
47
+ }, webglContextAttributes?: WebGLContextAttributes);
34
48
  _container: HTMLElement;
35
49
  _sizeSource: () => {
36
50
  width: any;
@@ -49,15 +63,11 @@ export default class WebGLHelper {
49
63
  /** @type {import("twgl.js").AttachmentOptions[]} */
50
64
  _pickingAttachmentOptions: import("twgl.js").AttachmentOptions[];
51
65
  _pickingBufferInfo: import("twgl.js").FramebufferInfo;
52
- /** @type {[number, number, number, number]} */
53
- _clearColor: [number, number, number, number];
54
66
  invalidateSize(): void;
55
67
  _logicalCanvasSize: {
56
68
  width: any;
57
69
  height: any;
58
70
  };
59
- _updateDpr(): void;
60
- dpr: number;
61
71
  /**
62
72
  * Compiles and caches a shader. The shader source is used as a cache key.
63
73
  *
@@ -80,19 +90,13 @@ export default class WebGLHelper {
80
90
  height: number;
81
91
  };
82
92
  /**
83
- * Returns the canvas size in logical pixels (without devicePixelRatio correction)
93
+ * Returns the size of the canvas canvas container size in logical pixels,
94
+ * without devicePixelRatio correction.
84
95
  */
85
96
  getLogicalCanvasSize(): {
86
97
  width: any;
87
98
  height: any;
88
99
  };
89
- /**
90
- *
91
- * @param {number} x
92
- * @param {number} y
93
- */
94
- readPickingPixel(x: number, y: number): Uint8Array<ArrayBuffer>;
95
- clearAll(): void;
96
100
  /**
97
101
  * Creates textures for color schemes and discrete/discretizing ranges.
98
102
  * N.B. Discrete range textures need domain. Thus, this cannot be called
@@ -1 +1 @@
1
- {"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AA2cA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,IAAI,CAAC,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AA/eD;IACI;;;;;;;;OAQG;IACH,uBAPW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,eAGrC,MAAM,2BACN,sBAAsB,EA8FhC;IAtFG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,6EAA6E;IAC7E,eADW,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,EAAE,YAAY,CAAC,CACvC;IAElC;;OAEG;IACH,mBAFU,OAAO,CAAC,OAAO,4BAA4B,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAEnD;IAwCtC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAOD,+CAA+C;IAC/C,aADW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CACZ;IAOnC,uBAIC;IAHG;;;MAAmC;IAKvC,mBAEC;IADG,YAAkC;IAGtC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAQ3C;IAED;;OAEG;IACH;;;MAuBC;IAED;;;;OAIG;IACH,oBAHW,MAAM,KACN,MAAM,2BAwBhB;IAED,iBAOC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,4BAA4B,EAAE,OAAO,WAC5C,OAAO,QA0GjB;IAED;;OAEG;IACH,kCAFW,OAAO,4BAA4B,EAAE,mBAAmB,0BA+BlE;CACJ"}
1
+ {"version":3,"file":"webGLHelper.d.ts","sourceRoot":"","sources":["../../../src/gl/webGLHelper.js"],"names":[],"mappings":"AAgZA;;;;GAIG;AACH,kCAJW,sBAAsB,gBACtB,WAAW,kBACX,WAAW;;;;;;EA8CrB;AAED;;;;;GAKG;AACH,0CALW,qBAAqB,WACrB,IAAI,CAAC,OAAO,SAAS,EAAE,cAAc,EAAE,KAAK,CAAC,OAC7C,MAAM,EAAE,GAAG,eAAe,YAC1B,YAAY,gBAYtB;AAED;;;;;;GAMG;AACH,qCALW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,KACjC,MAAM,KACN,MAAM,2BAWhB;AAED;;;;;GAKG;AACH,yCAJW,sBAAsB,mBACtB,OAAO,SAAS,EAAE,eAAe,SACjC,MAAM,UA4BhB;AAzeD;IACI;;;;;;;OAOG;IACH,uBANW,WAAW,eACX,MAAM;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,2BAGrC,sBAAsB,EA8EhC;IA3EG,wBAA2B;IAC3B;;;MAKO;IAEP,uCAAuC;IACvC,cADW,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CACN;IAE7B,6EAA6E;IAC7E,eADW,OAAO,CAAC,OAAO,qBAAqB,EAAE,SAAS,EAAE,YAAY,CAAC,CACvC;IAElC;;OAEG;IACH,mBAFU,OAAO,CAAC,OAAO,4BAA4B,EAAE,mBAAmB,EAAE,YAAY,CAAC,CAEnD;IAsCtC,0BAAoB;IACpB,2BAAY;IAGZ,oDAAoD;IACpD,2BADW,OAAO,SAAS,EAAE,iBAAiB,EAAE,CAQ/C;IACD,sDAGC;IAML,uBAGC;IAFG;;;MAAmC;IAIvC;;;;;OAKG;IACH,oBAHW,MAAM,QACN,MAAM,GAAG,MAAM,EAAE,eA2B3B;IAED,iBAcC;IAED,iBAEC;IAED;;;;OAIG;IACH,oCAFW;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;;;MAS3C;IAED;;;OAGG;IACH;;;MAuBC;IAED;;;;;;;;;OASG;IACH,+BAHW,OAAO,4BAA4B,EAAE,OAAO,WAC5C,OAAO,QA0GjB;IAED;;OAEG;IACH,kCAFW,OAAO,4BAA4B,EAAE,mBAAmB,0BA+BlE;CACJ"}
@@ -26,7 +26,6 @@ import {
26
26
  isColorChannel,
27
27
  isDiscreteChannel,
28
28
  } from "../encoder/encoder.js";
29
- import { color } from "d3-color";
30
29
  import { isMultiPointSelection } from "../selection/selection.js";
31
30
 
32
31
  export default class WebGLHelper {
@@ -36,15 +35,9 @@ export default class WebGLHelper {
36
35
  * @param {() => {width: number, height: number}} [sizeSource]
37
36
  * A function that returns the content size. If a dimension is undefined,
38
37
  * the canvas fills the container, otherwise the canvas is adjusted to the content size.
39
- * @param {string} [clearColor]
40
38
  * @param {WebGLContextAttributes} [webglContextAttributes]
41
39
  */
42
- constructor(
43
- container,
44
- sizeSource,
45
- clearColor,
46
- webglContextAttributes = {}
47
- ) {
40
+ constructor(container, sizeSource, webglContextAttributes = {}) {
48
41
  this._container = container;
49
42
  this._sizeSource =
50
43
  sizeSource ??
@@ -97,8 +90,6 @@ export default class WebGLHelper {
97
90
 
98
91
  addExtensionsToContext(gl);
99
92
 
100
- // TODO: view background: https://vega.github.io/vega-lite/docs/spec.html#view-background
101
-
102
93
  // Always use pre-multiplied alpha
103
94
  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
104
95
 
@@ -122,27 +113,13 @@ export default class WebGLHelper {
122
113
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
123
114
 
124
115
  this.adjustGl();
125
-
126
- this._updateDpr();
127
-
128
- /** @type {[number, number, number, number]} */
129
- this._clearColor = [0, 0, 0, 0];
130
- if (clearColor) {
131
- const c = color(clearColor).rgb();
132
- this._clearColor = [c.r / 255, c.g / 255, c.b / 255, c.opacity];
133
- }
134
116
  }
135
117
 
136
118
  invalidateSize() {
137
119
  this._logicalCanvasSize = undefined;
138
- this._updateDpr();
139
120
  this.adjustGl();
140
121
  }
141
122
 
142
- _updateDpr() {
143
- this.dpr = window.devicePixelRatio;
144
- }
145
-
146
123
  /**
147
124
  * Compiles and caches a shader. The shader source is used as a cache key.
148
125
  *
@@ -202,15 +179,17 @@ export default class WebGLHelper {
202
179
  * @param {{ width: number, height: number }} [logicalSize]
203
180
  */
204
181
  getPhysicalCanvasSize(logicalSize) {
182
+ const dpr = window.devicePixelRatio ?? 1;
205
183
  logicalSize = logicalSize || this.getLogicalCanvasSize();
206
184
  return {
207
- width: logicalSize.width * this.dpr,
208
- height: logicalSize.height * this.dpr,
185
+ width: logicalSize.width * dpr,
186
+ height: logicalSize.height * dpr,
209
187
  };
210
188
  }
211
189
 
212
190
  /**
213
- * Returns the canvas size in logical pixels (without devicePixelRatio correction)
191
+ * Returns the size of the canvas canvas container size in logical pixels,
192
+ * without devicePixelRatio correction.
214
193
  */
215
194
  getLogicalCanvasSize() {
216
195
  if (this._logicalCanvasSize) {
@@ -237,44 +216,6 @@ export default class WebGLHelper {
237
216
  return this._logicalCanvasSize;
238
217
  }
239
218
 
240
- /**
241
- *
242
- * @param {number} x
243
- * @param {number} y
244
- */
245
- readPickingPixel(x, y) {
246
- const gl = this.gl;
247
-
248
- x *= this.dpr;
249
- y *= this.dpr;
250
-
251
- const height = this.getPhysicalCanvasSize().height;
252
-
253
- const pixel = new Uint8Array(4);
254
- gl.bindFramebuffer(gl.FRAMEBUFFER, this._pickingBufferInfo.framebuffer);
255
- gl.readPixels(
256
- x,
257
- height - y - 1,
258
- 1,
259
- 1,
260
- gl.RGBA,
261
- gl.UNSIGNED_BYTE,
262
- pixel
263
- );
264
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
265
-
266
- return pixel;
267
- }
268
-
269
- clearAll() {
270
- const gl = this.gl;
271
- const { width, height } = this.getPhysicalCanvasSize();
272
- gl.viewport(0, 0, width, height);
273
- gl.disable(gl.SCISSOR_TEST);
274
- gl.clearColor(...this._clearColor);
275
- gl.clear(gl.COLOR_BUFFER_BIT);
276
- }
277
-
278
219
  /**
279
220
  * Creates textures for color schemes and discrete/discretizing ranges.
280
221
  * N.B. Discrete range textures need domain. Thus, this cannot be called
@@ -525,3 +466,55 @@ export function createOrUpdateTexture(gl, options, src, texture) {
525
466
  }
526
467
  return texture;
527
468
  }
469
+
470
+ /**
471
+ *
472
+ * @param {WebGL2RenderingContext} gl
473
+ * @param {import("twgl.js").FramebufferInfo} framebufferInfo
474
+ * @param {number} x
475
+ * @param {number} y
476
+ */
477
+ export function readPickingPixel(gl, framebufferInfo, x, y) {
478
+ const { height, framebuffer } = framebufferInfo;
479
+
480
+ const pixel = new Uint8Array(4);
481
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
482
+ gl.readPixels(x, height - y - 1, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
483
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
484
+
485
+ return pixel;
486
+ }
487
+
488
+ /**
489
+ *
490
+ * @param {WebGL2RenderingContext} gl
491
+ * @param {import("twgl.js").FramebufferInfo} framebufferInfo
492
+ * @param {string} [type]
493
+ */
494
+ export function framebufferToDataUrl(gl, framebufferInfo, type = "image/png") {
495
+ const { width, height } = framebufferInfo;
496
+ const pixels = new Uint8Array(width * height * 4);
497
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferInfo.framebuffer);
498
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
499
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
500
+
501
+ const exportCanvas = document.createElement("canvas");
502
+ exportCanvas.width = width;
503
+ exportCanvas.height = height;
504
+ const ctx = exportCanvas.getContext("2d");
505
+ const imageData = ctx.createImageData(width, height);
506
+
507
+ // Flip Y axis (WebGL's origin is bottom-left, canvas is top-left)
508
+ for (let y = 0; y < height; y++) {
509
+ const srcStart = (height - 1 - y) * width * 4;
510
+ const destStart = y * width * 4;
511
+ imageData.data.set(
512
+ pixels.subarray(srcStart, srcStart + width * 4),
513
+ destStart
514
+ );
515
+ }
516
+
517
+ ctx.putImageData(imageData, 0, 0);
518
+
519
+ return exportCanvas.toDataURL(type);
520
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";AAwGA;;;;;GAKG;AACH,8BAFW,MAAM,gBAuBhB;sBAhIqB,gBAAgB;qBAFjB,KAAK;iBAGT,kBAAkB;oBACf,6BAA6B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";AAyGA;;;;;GAKG;AACH,8BAFW,MAAM,gBAuBhB;sBAjIqB,gBAAgB;qBAFjB,KAAK;iBAGT,kBAAkB;oBACf,6BAA6B"}
package/dist/src/index.js CHANGED
@@ -88,6 +88,7 @@ export async function embed(el, spec, options = {}) {
88
88
  },
89
89
 
90
90
  updateNamedData: genomeSpy.updateNamedData.bind(genomeSpy),
91
+ exportCanvas: genomeSpy.exportCanvas.bind(genomeSpy),
91
92
  };
92
93
  }
93
94
 
@@ -256,11 +256,16 @@ export default class Mark<P extends import("../spec/mark.js").MarkProps = import
256
256
  /**
257
257
  * Sets viewport, clipping, and uniforms related to scaling and translation
258
258
  *
259
+ * @param {{width: number, height: number}} canvasSize Size of the canvas in logical pixels
260
+ * @param {number} dpr Device pixel ratio
259
261
  * @param {import("../view/layout/rectangle.js").default} coords
260
262
  * @param {import("../view/layout/rectangle.js").default} [clipRect]
261
263
  * @returns {boolean} true if the viewport is renderable (size > 0)
262
264
  */
263
- setViewport(coords: import("../view/layout/rectangle.js").default, clipRect?: import("../view/layout/rectangle.js").default): boolean;
265
+ setViewport(canvasSize: {
266
+ width: number;
267
+ height: number;
268
+ }, dpr: number, coords: import("../view/layout/rectangle.js").default, clipRect?: import("../view/layout/rectangle.js").default): boolean;
264
269
  /**
265
270
  * Finds a datum that overlaps the given value on the x domain.
266
271
  * The result is unspecified if multiple data are found.
@@ -1 +1 @@
1
- {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
@@ -1386,19 +1386,18 @@ export default class Mark {
1386
1386
  /**
1387
1387
  * Sets viewport, clipping, and uniforms related to scaling and translation
1388
1388
  *
1389
+ * @param {{width: number, height: number}} canvasSize Size of the canvas in logical pixels
1390
+ * @param {number} dpr Device pixel ratio
1389
1391
  * @param {import("../view/layout/rectangle.js").default} coords
1390
1392
  * @param {import("../view/layout/rectangle.js").default} [clipRect]
1391
1393
  * @returns {boolean} true if the viewport is renderable (size > 0)
1392
1394
  */
1393
- setViewport(coords, clipRect) {
1395
+ setViewport(canvasSize, dpr, coords, clipRect) {
1394
1396
  coords = coords.flatten();
1395
1397
 
1396
- const dpr = this.unitView.context.devicePixelRatio;
1397
1398
  const gl = this.gl;
1398
1399
  const props = this.properties;
1399
1400
 
1400
- const logicalSize = this.glHelper.getLogicalCanvasSize();
1401
-
1402
1401
  // Translate by half a pixel to place vertical / horizontal
1403
1402
  // rules inside pixels, not between pixels.
1404
1403
  const pixelOffset = 0.5;
@@ -1442,7 +1441,7 @@ export default class Mark {
1442
1441
 
1443
1442
  const physicalGlCoords = [
1444
1443
  clippedCoords.x,
1445
- logicalSize.height - clippedCoords.y2,
1444
+ canvasSize.height - clippedCoords.y2,
1446
1445
  clippedCoords.width,
1447
1446
  clippedCoords.height,
1448
1447
  ].map((x) => x * dpr);
@@ -1476,24 +1475,19 @@ export default class Mark {
1476
1475
  }
1477
1476
 
1478
1477
  // Viewport comprises the full canvas
1479
- gl.viewport(
1480
- 0,
1481
- 0,
1482
- logicalSize.width * dpr,
1483
- logicalSize.height * dpr
1484
- );
1478
+ gl.viewport(0, 0, canvasSize.width * dpr, canvasSize.height * dpr);
1485
1479
  gl.disable(gl.SCISSOR_TEST);
1486
1480
 
1487
1481
  // Offset and scale all drawing to the view rectangle
1488
1482
  uniforms = {
1489
1483
  uViewOffset: [
1490
- (coords.x + xOffset) / logicalSize.width,
1491
- (logicalSize.height - coords.y - yOffset - coords.height) /
1492
- logicalSize.height,
1484
+ (coords.x + xOffset) / canvasSize.width,
1485
+ (canvasSize.height - coords.y - yOffset - coords.height) /
1486
+ canvasSize.height,
1493
1487
  ],
1494
1488
  uViewScale: [
1495
- coords.width / logicalSize.width,
1496
- coords.height / logicalSize.height,
1489
+ coords.width / canvasSize.width,
1490
+ coords.height / canvasSize.height,
1497
1491
  ],
1498
1492
  };
1499
1493
  }
@@ -1,2 +1,2 @@
1
- const shader = "out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nout vec2 vPosInPixels;\n#endif\nout vec2 vHalfSizeInPixels;/***Clamps the minimumSize and returns an opacity that reflects the amount of clamping.*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&abs(size)<minSize){pos+=(frac-0.5)*(minSize*sign(size)-size);return abs(size)/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<=0.0||size.y<=0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nfloat aaPadding=1.0/uDevicePixelRatio;float shadowPadding=uShadowBlur+max(abs(uShadowOffsetX),abs(uShadowOffsetY));float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding+shadowPadding*2.0)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
1
+ const shader = "out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nout vec2 vPosInPixels;\n#endif\nout vec2 vHalfSizeInPixels;/***Adjusts the vertex position to ensure that the rectangle is at least `minSpan`*wide or high. Returns a value that reflects the amount of clamping and can be*used to adjust the opacity of the rectangle.**pos: vertex position*frac: vertex position within the rectangle,[0,1]*size: width or height of the rectangle*minSize: minimum width or height of the rectangle*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&size<minSize){pos+=(frac-0.5)*(minSize-size);return size/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<=0.0||size.y<=0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));size=max(size,normalizedMinSize);pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nfloat aaPadding=1.0/uDevicePixelRatio;float shadowPadding=uShadowBlur+max(abs(uShadowOffsetX),abs(uShadowOffsetY));float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding+shadowPadding*2.0)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
2
2
  export default shader;
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/marks/text.js"],"names":[],"mappings":"AAgCA;;;;;;;;;GASG;AACH;IACI;;OAEG;IACH;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EA8D/C;IAbG,oDAMmD;CA+M1D;iBAxSgB,WAAW"}
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/marks/text.js"],"names":[],"mappings":"AAgCA;;;;;;;;;GASG;AACH;IACI;;OAEG;IACH;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EA8D/C;IAbG,oDAMmD;CAuM1D;iBAhSgB,WAAW"}