@genome-spy/core 0.62.1 → 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 (35) hide show
  1. package/dist/bundle/index.es.js +4302 -4236
  2. package/dist/bundle/index.js +97 -97
  3. package/dist/src/encoder/encoder.d.ts +4 -0
  4. package/dist/src/encoder/encoder.d.ts.map +1 -1
  5. package/dist/src/encoder/encoder.js +14 -0
  6. package/dist/src/genomeSpy.d.ts +11 -0
  7. package/dist/src/genomeSpy.d.ts.map +1 -1
  8. package/dist/src/genomeSpy.js +98 -20
  9. package/dist/src/gl/includes/common.glsl.js +1 -1
  10. package/dist/src/gl/webGLHelper.d.ts +18 -14
  11. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  12. package/dist/src/gl/webGLHelper.js +58 -65
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +1 -0
  15. package/dist/src/marks/mark.d.ts +6 -1
  16. package/dist/src/marks/mark.d.ts.map +1 -1
  17. package/dist/src/marks/mark.js +14 -19
  18. package/dist/src/marks/markUtils.d.ts.map +1 -1
  19. package/dist/src/marks/markUtils.js +4 -8
  20. package/dist/src/marks/rect.vertex.glsl.js +1 -1
  21. package/dist/src/marks/text.d.ts.map +1 -1
  22. package/dist/src/marks/text.js +7 -15
  23. package/dist/src/marks/text.vertex.glsl.js +1 -1
  24. package/dist/src/types/embedApi.d.ts +16 -0
  25. package/dist/src/types/viewContext.d.ts +0 -2
  26. package/dist/src/view/gridView/gridView.js +1 -1
  27. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts +32 -17
  28. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
  29. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +85 -39
  30. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
  31. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +5 -1
  32. package/dist/src/view/renderingContext/viewRenderingContext.d.ts +1 -0
  33. package/dist/src/view/renderingContext/viewRenderingContext.d.ts.map +1 -1
  34. package/dist/src/view/renderingContext/viewRenderingContext.js +4 -0
  35. package/package.json +2 -2
@@ -42,6 +42,10 @@ export function isDatumDef(channelDef: import("../spec/channel.js").ChannelDef):
42
42
  * @returns {channelDef is import("../spec/channel.js").ChannelDefWithScale}
43
43
  */
44
44
  export function isChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): channelDef is import("../spec/channel.js").ChannelDefWithScale;
45
+ /**
46
+ * @param {import("../spec/channel.js").ChannelDef} channelDef
47
+ */
48
+ export function findChannelDefWithScale(channelDef: import("../spec/channel.js").ChannelDef): import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, string> | import("../spec/channel.js").PositionFieldDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").FieldOrDatumDefWithCondition<import("../spec/channel.js").MarkPropFieldDef<import("../spec/channel.js").Type>, number> | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").FieldDefBase & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").DatumDef<import("../spec/parameter.js").ExprRef | import("../spec/channel.js").Scalar> & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<string | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>) | (import("../spec/channel.js").ParameterPredicate & import("../spec/channel.js").ValueDefBase<number | import("../spec/parameter.js").ExprRef> & import("../spec/channel.js").TitleMixins & import("../spec/channel.js").ScaleMixins & import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>);
45
49
  /**
46
50
  * @param {import("../view/unitView.js").default} view
47
51
  * @param {import("../spec/channel.js").Channel} channel
@@ -1 +1 @@
1
- {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"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"}
@@ -217,6 +217,20 @@ export function isChannelDefWithScale(channelDef) {
217
217
  );
218
218
  }
219
219
 
220
+ /**
221
+ * @param {import("../spec/channel.js").ChannelDef} channelDef
222
+ */
223
+ export function findChannelDefWithScale(channelDef) {
224
+ if (isValueDefWithCondition(channelDef)) {
225
+ const condition = channelDef.condition;
226
+ if (!Array.isArray(condition) && isChannelDefWithScale(condition)) {
227
+ return condition;
228
+ }
229
+ } else if (isChannelDefWithScale(channelDef)) {
230
+ return channelDef;
231
+ }
232
+ }
233
+
220
234
  /**
221
235
  * @param {import("../view/unitView.js").default} view
222
236
  * @param {import("../spec/channel.js").Channel} channel
@@ -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":"AA0DA,mCAAoC,sBAAsB,CAAC;AAC3D,mCAAoC,sBAAsB,CAAC;AAE3D,uCAAwC,oBAAoB,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,0BAF0B,CAAC,SAAd,mCAAW;IAkBpB;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EA4G/C;IAzGG,gDAAwB;IAExB,8EAA8E;IAC9E,UADW,OAAO,CAAC,MAAM,uCAAU,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,CACjD;IAIzB;;;OAGG;IACH,sBAHU,OAAO,SAAS,EAAE,UAAU,GAAG;QAAE,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,CAG5C;IAE3B;;;;;;;OAOG;IACH,2BAHU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAGG;IAEhC;;;OAGG;IACH,uBAHU,OAAO,SAAS,EAAE,WAAW,CAGX;IAE5B;;;OAGG;IACH,2BAHU,OAAO,SAAS,EAAE,eAAe,CAGX;IAEhC;;;OAGG;IACH,2BAHU,OAAO,SAAS,EAAE,gBAAgB,CAGZ;IAEhC;;;;;OAKG;IACH,2BAHU,OAAO,SAAS,EAAE,gBAAgB,CAGZ;IAEhC;;;;;OAKG;IACH,uCAA+B;IAE/B;;;;;OAKG;IACH,4BAA6B;IAE7B,kFAAkF;IAClF,UADW,QAAQ,CAAC,GAAG,CAAC,CACM;IAG9B,qBAqBE;IAEF;;;;;;OAMG;IACH,qBAHU,CAAC,CAQV;IAGL;;;OAGG;IACH,0CAHW,OAAO,CAAC,CAAC,CAAC,QAQpB;IAED,sBAEC;IAED;;;OAGG;IACH,0BAFa,WAAW,CAIvB;IAED;;;;;OAKG;IACH,2BAHa,OAAO,oBAAoB,EAAE,OAAO,EAAE,CAMlD;IAED;;OAEG;IACH,wBAFa,sCAAS,CAarB;IAED;;OAEG;IACH,4DAcC;IAED;;;;;OAKG;IACH,oGAEC;IAED;;;;;;OAMG;IACH,oDAHW,CAAC,MAAM,CAAC,CAAC,EAAE,QAqCrB;IAED;;;;OAIG;IACH,sDAiDC;IAED,wDAEC;IAED,uDAEC;IAED,uBAEC;IAED;;;OAGG;IACH,2BAEC;IAED;;OAEG;IACH,oCAEC;IAED;;OAEG;IACH,2BAEC;IAED,sEAeC;IAED;;;;;;OAMG;IAEH,6CANW,MAAM,kBACN,MAAM,iBACN,MAAM,EAAE,QAoelB;IALG;;;;;;MAIC;IAGL;;;;;;OAMG;IACH,uCA6CC;IAED;;;;;;OAMG;IACH,+CAHW,MAAM,GACJ,CAAS,IAAG,EAAH,GAAG,KAAE,IAAI,CAe9B;IAED;;;;;;;;;;OAUG;IACH,mCALa,CAAC,eACH,MAAM,aACN,CAAC,aACD,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,yCAAU,KAAK,GAAG,QA6BzC;IAED;;OAEG;IACH,2BAwBC;IAED;;;OAGG;IACH,6BAFW,GAAG,QAyCb;IAED,yBAAyB;IACzB,uDAEC;IAED,yBAAyB;IACzB,iCAEC;IAED,gCAEC;IAED,+BAEC;IAED,yCAEC;IAED;;OAEG;IACH,gCAgBC;IAED;;OAEG;IACH,4CAOC;IAED;;;;;;;;OAQG;IAEH,uBAJW,OAAO,uBAAuB,EAAE,sBAAsB,GACpD,CAAC,MAAM,IAAI,CAAC,EAAE,CA4E1B;IAED;;;;;;OAMG;IACH,qCAJW,oBAAoB,GAClB,OAAO,CAqCnB;IAED;;;;;;;OAOG;IACH,gBAJW,oBAAoB,GAClB,MAAW,IAAI,CAM3B;IAED;;;;OAIG;IACH,2BAJW,YAAY,WACZ,OAAO,WAAW,EAAE,oBAAoB,GACtC,MAAW,IAAI,CAmE3B;IAED;;;;;;;;OAQG;IACH,wBANW;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,OAC/B,MAAM,UACN,OAAO,6BAA6B,EAAE,OAAO,aAC7C,OAAO,6BAA6B,EAAE,OAAO,GAC3C,OAAO,CA+GnB;IAED;;;;;;;;;OASG;IACH,qBAJW,MAAM,KACN,OAAO,oBAAoB,EAAE,MAAM,GACjC,GAAG,CAIf;;CACJ;+BA76CY,OAAO,uBAAuB,EAAE,gBAAgB;;;;;;wBAEnD,OAAO;;mCAEJ,gBAAgB,GAAG,qBAAqB;oCAG1C,MAAM,SACN,MAAM;0BAEJ,YAAY,GAAG,UAAU,GAAG,WAAW;AAq6CpD;;;GAGG;AACH,uBAFa,CAAC;IAGV,cAEC;IAkBD;;;OAGG;IACH,2BAFW,GAAG,CAAC,CAAC,EAAE,OAAO,yBAAyB,EAAE,UAAU,CAAC,QAiB9D;CACJ;0BA7+CyB,WAAW"}