@genome-spy/core 0.47.0 → 0.48.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.
- package/dist/bundle/index.es.js +3332 -3209
- package/dist/bundle/index.js +84 -84
- package/dist/schema.json +9 -2
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +10 -3
- package/dist/src/marks/link.common.glsl.js +1 -1
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +14 -22
- package/dist/src/marks/link.vertex.glsl.js +1 -1
- package/dist/src/marks/mark.d.ts +9 -0
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +19 -0
- package/dist/src/marks/rect.vertex.glsl.js +1 -1
- package/dist/src/spec/mark.d.ts +1 -1
- package/dist/src/utils/animator.d.ts +7 -4
- package/dist/src/utils/animator.d.ts.map +1 -1
- package/dist/src/utils/animator.js +45 -17
- package/dist/src/utils/inertia.d.ts +5 -1
- package/dist/src/utils/inertia.d.ts.map +1 -1
- package/dist/src/utils/inertia.js +6 -5
- package/dist/src/utils/ringBuffer.d.ts +19 -0
- package/dist/src/utils/ringBuffer.d.ts.map +1 -0
- package/dist/src/utils/ringBuffer.js +43 -0
- package/dist/src/utils/ringBuffer.test.js +39 -0
- package/dist/src/view/gridView.d.ts +5 -1
- package/dist/src/view/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView.js +10 -8
- package/dist/src/view/layout/point.d.ts +17 -1
- package/dist/src/view/layout/point.d.ts.map +1 -1
- package/dist/src/view/layout/point.js +36 -1
- package/dist/src/view/zoom.d.ts +3 -9
- package/dist/src/view/zoom.d.ts.map +1 -1
- package/dist/src/view/zoom.js +133 -8
- package/package.json +2 -2
package/dist/schema.json
CHANGED
|
@@ -3471,8 +3471,15 @@
|
|
|
3471
3471
|
"description": "The vertical padding, in pixels, when the `y2` channel is used for ranged text.\n\n**Default value:** `0`"
|
|
3472
3472
|
},
|
|
3473
3473
|
"segments": {
|
|
3474
|
-
"
|
|
3475
|
-
|
|
3474
|
+
"anyOf": [
|
|
3475
|
+
{
|
|
3476
|
+
"type": "number"
|
|
3477
|
+
},
|
|
3478
|
+
{
|
|
3479
|
+
"$ref": "#/definitions/ExprRef"
|
|
3480
|
+
}
|
|
3481
|
+
],
|
|
3482
|
+
"description": "The number of segments in the bézier curve. Affects the rendering quality and performance. Use a higher value for a smoother curve.\n\n**Default value:* `101`"
|
|
3476
3483
|
},
|
|
3477
3484
|
"semanticZoomFraction": {
|
|
3478
3485
|
"anyOf": [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"genomeSpy.d.ts","sourceRoot":"","sources":["../../src/genomeSpy.js"],"names":[],"mappings":"AA+CA;IACI;;;;;OAKG;IAEH;;;;;OAKG;IACH,uBAJW,WAAW,qDAEX,OAAO,qBAAqB,EAAE,YAAY,EA2FpD;IAxFG,uBAA0B;IAC1B,oDAAsB;IAItB,6BAA6B;IAC7B,uBADW,CAAC,MAAM,IAAI,CAAC,EAAE,CACM;IAE/B,sCAAsC;IACtC,wCAAgB;IAEhB,iCAA4C;IAC5C,yBAAoC;IAEpC,4CAA4C;IAC5C,oBADW,QAAU,MAAM,KAAE,MAAM,EAAE,CAAC,EAAE,CACZ;IAE5B,mBAAoD;IAEpD,0BAA0B;IAC1B,aADW,WAAW,CACM;IAE5B;;;;;OAKG;IACH,qEAF0B,OAAO,CAE8B;IAE/D,2CAA2C;IAC3C,mBADW,4BAA4B,CACL;IAClC,2CAA2C;IAC3C,iBADW,4BAA4B,CACP;IAEhC,oDAAoD;IACpD,6BAAgC;IAEhC;;;OAGG;IACH,eAFU;QAAE,IAAI,EAAE,OAAO,iBAAiB,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,oBAAoB,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAEpF;IAE9B,uBAA+C;IAE/C;;;OAGG;IACH,oBAFU,IAAI,MAAM,EAAE,QAAU,aAAa,KAAE,IAAI,CAAC,EAAE,CAAC,CAEpB;IAEnC;;;;;;OAMG;IACH,yCAFkC,GAAG,KAAK,IAAI,GAEd;IAEhC;;;OAGG;IACH,kDAFkC,GAAG,KAAK,IAAI,GAEL;IAEzC,oFAAoF;IACpF,iBADW,OAAO,MAAM,EAAE,OAAO,6BAA6B,EAAE,cAAc,CAAC,CAK9E;IAED,mBAAmB;IACnB,2CAAyB;IAEzB;;;;OAIG;IACH;gBAF8B,OAAO,wBAAwB,EAAE,iBAAiB;iBAAW,MAAM;OAEnE;IAE9B;;OAEG;IACH,wBAFU,WAAW,CAEkB;IA2C3C;;;OAGG;IACH,2CAFkB,MAAM,KAAK,GAAG,EAAE,QAIjC;IAED;;OAEG;IACH,+BAFW,MAAM,YAShB;IAED;;;;OAIG;IACH,sBAHW,MAAM,QACN,GAAG,EAAE,QAaf;IAED;;;;;OAKG;IACH,gBAHW,kBAAkB,YAClB,GAAG,QAQb;IAED;;;OAGG;IACH,iCAqDC;IA0DG,uBAQC;IAGD,mCAGE;IAOF,sCAEE;IAGF,iBAAyC;IAW7C;;OAEG;IACH,gBAuBC;IAED,sCA8MC;IAED;;;OAGG;IACH,UAFa,QAAQ,OAAO,CAAC,CA6B5B;IAED,4BAqJC;IA9He,iCAAoC;IAgIpD;;;OAGG;IACH,kBAHW,MAAM,KACN,MAAM,QAsEhB;IAED;;;;;;;OAOG;IACH,oDAHuB,QAAQ,MAAM,GAAG,WAAW,GAAG,OAAO,KAAK,EAAE,cAAc,CAAC,QAYlF;IAED,sBA6CC;IAED,kBAIC;IAED,iCAOC;IAED,iCASC;IAED,qFAWC;;CACJ;;;;iCAx7BY,eAAe,GAAG,YAAY,GAAG,QAAQ,GAAG,gBAAgB;4BAlC7C,uBAAuB;4BA2BP,uBAAuB;qBAZ9C,qBAAqB;wBAIlB,yBAAyB;yCARR,yDAAyD;oBAYvD,oBAAoB;wBAdvC,qBAAqB;oBAXzB,uBAAuB;qBAStB,oBAAoB"}
|
package/dist/src/genomeSpy.js
CHANGED
|
@@ -36,6 +36,7 @@ import { invalidatePrefix } from "./utils/propertyCacher.js";
|
|
|
36
36
|
import { VIEW_ROOT_NAME, ViewFactory } from "./view/viewFactory.js";
|
|
37
37
|
import { reconfigureScales } from "./view/scaleResolution.js";
|
|
38
38
|
import createBindingInputs from "./utils/inputBinding.js";
|
|
39
|
+
import { isStillZooming } from "./view/zoom.js";
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Events that are broadcasted to all views.
|
|
@@ -687,8 +688,10 @@ export default class GenomeSpy {
|
|
|
687
688
|
this.tooltip.handleMouseMove(event);
|
|
688
689
|
this._tooltipUpdateRequested = false;
|
|
689
690
|
|
|
690
|
-
|
|
691
|
-
|
|
691
|
+
// Disable picking during dragging. Also postpone picking until
|
|
692
|
+
// the user has stopped zooming as reading pixels from the
|
|
693
|
+
// picking buffer is slow and ruins smooth animations.
|
|
694
|
+
if (event.buttons == 0 && !isStillZooming()) {
|
|
692
695
|
this.renderPickingFramebuffer();
|
|
693
696
|
this._handlePicking(point.x, point.y);
|
|
694
697
|
}
|
|
@@ -711,7 +714,11 @@ export default class GenomeSpy {
|
|
|
711
714
|
this._wheelInertia.cancel();
|
|
712
715
|
}
|
|
713
716
|
|
|
714
|
-
if (
|
|
717
|
+
if (
|
|
718
|
+
(event.type == "mousedown" || event.type == "mouseup") &&
|
|
719
|
+
!isStillZooming()
|
|
720
|
+
) {
|
|
721
|
+
// Actually, only needed when clicking on a mark
|
|
715
722
|
this.renderPickingFramebuffer();
|
|
716
723
|
} else if (event.type == "wheel") {
|
|
717
724
|
lastWheelEvent = now;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "layout(std140)uniform Mark{uniform float uArcHeightFactor;uniform float uMinArcHeight;uniform float uMinPickingSize;uniform int uShape;uniform int uOrient;uniform bool uClampApex;uniform float uMaxChordLength;uniform vec2 uArcFadingDistance;\n#pragma markUniforms\n};";
|
|
1
|
+
const shader = "layout(std140)uniform Mark{uniform float uArcHeightFactor;uniform float uMinArcHeight;uniform float uMinPickingSize;uniform int uShape;uniform int uOrient;uniform bool uClampApex;uniform float uMaxChordLength;uniform vec2 uArcFadingDistance;uniform int uSegmentBreaks;\n#pragma markUniforms\n};";
|
|
2
2
|
export default shader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"AAYA;IA+BQ;;;;;OAKG;IACH,yBAEC;
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"AAYA;IA+BQ;;;;;OAKG;IACH,yBAEC;IA2GD;;;;;;MAKC;CAwFR;iBArPgB,WAAW"}
|
package/dist/src/marks/link.js
CHANGED
|
@@ -133,6 +133,11 @@ export default class LinkMark extends Mark {
|
|
|
133
133
|
(x) => !!x
|
|
134
134
|
);
|
|
135
135
|
this.registerMarkUniformValue("uMaxChordLength", props.maxChordLength);
|
|
136
|
+
this.registerMarkUniformValue(
|
|
137
|
+
"uSegmentBreaks",
|
|
138
|
+
props.segments,
|
|
139
|
+
(x) => x + 1
|
|
140
|
+
);
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
updateGraphicsData() {
|
|
@@ -149,12 +154,6 @@ export default class LinkMark extends Mark {
|
|
|
149
154
|
|
|
150
155
|
const vertexData = builder.toArrays();
|
|
151
156
|
|
|
152
|
-
// TODO: Use gl_VertexID to calculate the strip in the vertex shader
|
|
153
|
-
vertexData.arrays.strip = {
|
|
154
|
-
data: createStrip(this.properties.segments),
|
|
155
|
-
numComponents: 2,
|
|
156
|
-
};
|
|
157
|
-
|
|
158
157
|
this.rangeMap.migrateEntries(vertexData.rangeMap);
|
|
159
158
|
|
|
160
159
|
this.arrays = Object.fromEntries(
|
|
@@ -196,8 +195,6 @@ export default class LinkMark extends Mark {
|
|
|
196
195
|
render(options) {
|
|
197
196
|
const gl = this.gl;
|
|
198
197
|
|
|
199
|
-
const arcVertexCount = (this.properties.segments + 1) * 2;
|
|
200
|
-
|
|
201
198
|
return this._baseInstanceExt
|
|
202
199
|
? this.createRenderCallback((offset, count) => {
|
|
203
200
|
// Using the following extension, which, however, is only a draft and
|
|
@@ -207,7 +204,9 @@ export default class LinkMark extends Mark {
|
|
|
207
204
|
this._baseInstanceExt.drawArraysInstancedBaseInstanceWEBGL(
|
|
208
205
|
gl.TRIANGLE_STRIP,
|
|
209
206
|
0,
|
|
210
|
-
|
|
207
|
+
/** @type {Float32Array} */ (
|
|
208
|
+
this.markUniformInfo.uniforms.uSegmentBreaks
|
|
209
|
+
)[0] * 2,
|
|
211
210
|
count,
|
|
212
211
|
offset
|
|
213
212
|
);
|
|
@@ -229,7 +228,9 @@ export default class LinkMark extends Mark {
|
|
|
229
228
|
attribInfo.divisor
|
|
230
229
|
) {
|
|
231
230
|
attribInfo.offset =
|
|
232
|
-
offset *
|
|
231
|
+
offset *
|
|
232
|
+
this.arrays[attribute].numComponents *
|
|
233
|
+
this.bytesPerElement.get(attribute);
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
236
|
setBuffersAndAttributes(
|
|
@@ -241,20 +242,11 @@ export default class LinkMark extends Mark {
|
|
|
241
242
|
gl.drawArraysInstanced(
|
|
242
243
|
gl.TRIANGLE_STRIP,
|
|
243
244
|
0,
|
|
244
|
-
|
|
245
|
+
/** @type {Float32Array} */ (
|
|
246
|
+
this.markUniformInfo.uniforms.uSegmentBreaks
|
|
247
|
+
)[0] * 2,
|
|
245
248
|
count
|
|
246
249
|
);
|
|
247
250
|
}, options);
|
|
248
251
|
}
|
|
249
252
|
}
|
|
250
|
-
|
|
251
|
-
function createStrip(/** @type number */ segments) {
|
|
252
|
-
let i = 0;
|
|
253
|
-
const coords = [];
|
|
254
|
-
|
|
255
|
-
for (; i <= segments; i++) {
|
|
256
|
-
coords.push(i / segments, 0.5);
|
|
257
|
-
coords.push(i / segments, -0.5);
|
|
258
|
-
}
|
|
259
|
-
return new Float32Array(coords);
|
|
260
|
-
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "
|
|
1
|
+
const shader = "out vec4 vColor;out float vSize;out float vNormalLengthInPixels;const int SHAPE_ARC=0;const int SHAPE_DOME=1;const int SHAPE_DIAGONAL=2;const int SHAPE_LINE=3;const int ORIENT_VERTICAL=0;const int ORIENT_HORIZONTAL=1;float distanceFromLine(vec2 pointOnLine1,vec2 pointOnLine2,vec2 point){vec2 a=point-pointOnLine1;vec2 b=pointOnLine2-pointOnLine1;vec2 proj=dot(a,b)/dot(b,b)*b;return length(a-proj);}bool isInsideViewport(vec2 point,float marginFactor){vec2 margin=uViewportSize*vec2(marginFactor);return point.x>=-margin.x&&point.x<=uViewportSize.x+margin.x&&point.y>=-margin.y&&point.y<=uViewportSize.y+margin.y;}void main(void){float pixelSize=1.0/uDevicePixelRatio;float opacity=getScaled_opacity()*uViewOpacity;vec2 p1,p2,p3,p4;vec2 a=applySampleFacet(vec2(getScaled_x(),getScaled_y()))*uViewportSize;vec2 b=applySampleFacet(vec2(getScaled_x2(),getScaled_y2()))*uViewportSize;if(uShape<=SHAPE_DOME){if(uShape==SHAPE_DOME){vec2 height=vec2(0.0);if(uOrient==ORIENT_VERTICAL){p1=vec2(min(a.x,b.x),b.y);p4=vec2(max(a.x,b.x),b.y);height=vec2(0.0,a.y-b.y);if(uClampApex){if(p4.x>0.0){p1.x=max(p1.x,-p4.x);}if(p1.x<uViewportSize.x){p4.x=min(p4.x,2.0*uViewportSize.x-p1.x);}}}else{p1=vec2(b.x,min(a.y,b.y));p4=vec2(b.x,max(a.y,b.y));height=vec2(a.x-b.x,0.0);if(uClampApex){if(p4.y>0.0){p1.y=max(p1.y,-p4.y);}if(p1.y<uViewportSize.y){p4.y=min(p4.y,2.0*uViewportSize.y-p1.y);}}}vec2 controlOffset=height/0.75;p2=p1+controlOffset;p3=p4+controlOffset;}if(uShape==SHAPE_ARC){p1=a;p4=b;vec2 chordVector=p4-p1;vec2 unitChordVector=normalize(chordVector);vec2 chordNormal=vec2(-unitChordVector.y,unitChordVector.x);float chordLength=length(chordVector);if(chordLength>uMaxChordLength){if(isInsideViewport(p1,2.0)){chordLength=uMaxChordLength;p4=p1+unitChordVector*uMaxChordLength;}else if(isInsideViewport(p4,2.0)){chordLength=uMaxChordLength;p1=p4-unitChordVector*uMaxChordLength;}}float height=max(chordLength/2.0*uArcHeightFactor,uMinArcHeight);vec2 controlOffset=chordNormal*height/0.75;p2=p1+controlOffset;p3=p4+controlOffset;}}else if(uShape==SHAPE_DIAGONAL){if(uOrient==ORIENT_VERTICAL){p1=a;p2=vec2(a.x,(a.y+b.y)/2.0);p3=vec2(b.x,(a.y+b.y)/2.0);p4=b;}else{p1=a;p2=vec2((a.x+b.x)/2.0,a.y);p3=vec2((a.x+b.x)/2.0,b.y);p4=b;}}else if(uShape==SHAPE_LINE){p1=a;p2=(a+b)/2.0;p3=p2;p4=b;}vec2 strip=vec2(float(gl_VertexID/2)/float(uSegmentBreaks),float(gl_VertexID % 2)-0.5);float t=smoothstep(0.0,1.0,strip.x);vec2 C1=p4-3.0*p3+3.0*p2-p1;vec2 C2=3.0*p3-6.0*p2+3.0*p1;vec2 C3=3.0*p2-3.0*p1;vec2 C4=p1;vec2 p;if(t==0.0){p=p1;}else if(t==1.0){p=p4;}else{p=C1*t*t*t+C2*t*t+C3*t+C4;}vec2 tangent=normalize(3.0*C1*t*t+2.0*C2*t+C3);vec2 normal=vec2(-tangent.y,tangent.x);float size=getScaled_size();if(size<pixelSize){opacity*=size/pixelSize;size=pixelSize;}float paddedSize=uPickingEnabled? max(size,uMinPickingSize): size+pixelSize;vNormalLengthInPixels=strip.y*paddedSize;if(uShape==SHAPE_ARC&&uArcFadingDistance[0]>0.0&&uArcFadingDistance[1]>0.0){float d=distanceFromLine(p1,p4,p);float distanceOpacity=smoothstep(uArcFadingDistance[1],uArcFadingDistance[0],d);opacity*=distanceOpacity;if(distanceOpacity<=0.0){vNormalLengthInPixels=0.0;}}p+=normal*vNormalLengthInPixels;gl_Position=pixelsToNdc(p);vec3 color=getScaled_color();vColor=vec4(color*opacity,opacity);vSize=paddedSize;setupPicking();}";
|
|
2
2
|
export default shader;
|
package/dist/src/marks/mark.d.ts
CHANGED
|
@@ -29,6 +29,15 @@ export default class Mark {
|
|
|
29
29
|
protected bufferInfo: import("twgl.js").BufferInfo & {
|
|
30
30
|
allocatedVertices?: number;
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* TWGL's BufferInfo doesn't contain the number of bytes per element,
|
|
34
|
+
* so we need to keep track of it separately. This is mainly used by
|
|
35
|
+
* the instancing hack in the link mark.
|
|
36
|
+
*
|
|
37
|
+
* @type {Map<string, number>}
|
|
38
|
+
* @protected
|
|
39
|
+
*/
|
|
40
|
+
protected bytesPerElement: Map<string, number>;
|
|
32
41
|
/**
|
|
33
42
|
* @type {import("twgl.js").ProgramInfo}
|
|
34
43
|
* @protected
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":";AA4CA,0DAA2D;AAC3D,0DAA2D;AAE3D;;;;;;;;;;;;GAYG;AACH;IAgBI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
|
package/dist/src/marks/mark.js
CHANGED
|
@@ -91,6 +91,16 @@ export default class Mark {
|
|
|
91
91
|
*/
|
|
92
92
|
this.bufferInfo = undefined;
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* TWGL's BufferInfo doesn't contain the number of bytes per element,
|
|
96
|
+
* so we need to keep track of it separately. This is mainly used by
|
|
97
|
+
* the instancing hack in the link mark.
|
|
98
|
+
*
|
|
99
|
+
* @type {Map<string, number>}
|
|
100
|
+
* @protected
|
|
101
|
+
*/
|
|
102
|
+
this.bytesPerElement = new Map();
|
|
103
|
+
|
|
94
104
|
/**
|
|
95
105
|
* @type {import("twgl.js").ProgramInfo}
|
|
96
106
|
* @protected
|
|
@@ -788,6 +798,15 @@ export default class Mark {
|
|
|
788
798
|
{ numElements: vertexData.vertexCount }
|
|
789
799
|
);
|
|
790
800
|
this.bufferInfo.allocatedVertices = vertexData.allocatedVertices;
|
|
801
|
+
|
|
802
|
+
for (const [attribute, attributeData] of Object.entries(
|
|
803
|
+
vertexData.arrays
|
|
804
|
+
)) {
|
|
805
|
+
this.bytesPerElement.set(
|
|
806
|
+
attribute,
|
|
807
|
+
attributeData.data.BYTES_PER_ELEMENT
|
|
808
|
+
);
|
|
809
|
+
}
|
|
791
810
|
}
|
|
792
811
|
}
|
|
793
812
|
|
|
@@ -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)\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,uCornerRadiusBottomLeft
|
|
1
|
+
const shader = "out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\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)\nfloat aaPadding=1.0/uDevicePixelRatio;float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding)/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;
|
package/dist/src/spec/mark.d.ts
CHANGED
|
@@ -349,7 +349,7 @@ export interface LinkProps extends SecondaryPositionProps {
|
|
|
349
349
|
*
|
|
350
350
|
* **Default value:* `101`
|
|
351
351
|
*/
|
|
352
|
-
segments?: number;
|
|
352
|
+
segments?: number | ExprRef;
|
|
353
353
|
|
|
354
354
|
/**
|
|
355
355
|
* Scaling factor for the `"arc`" shape's height. The default value `1.0` produces roughly circular arcs.
|
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
* Read more at: https://www.gamedeveloper.com/programming/improved-lerp-smoothing-
|
|
7
7
|
*
|
|
8
8
|
* @param {import("../utils/animator.js").default} animator
|
|
9
|
-
* @param {(value:
|
|
9
|
+
* @param {(value: T) => void} callback Function to be called with the interpolated value
|
|
10
10
|
* @param {number} halfLife Time until half of the value is reached, in milliseconds
|
|
11
11
|
* @param {number} stopAt Stop animation when the value is within this distance from the target
|
|
12
|
-
* @param {
|
|
13
|
-
* @returns {(target:
|
|
12
|
+
* @param {T} initialValue Initial value
|
|
13
|
+
* @returns {((target: T) => void) & { stop: () => void}} Function that activates the transition with a new target value
|
|
14
|
+
* @template {Record<string, number>} T
|
|
14
15
|
*/
|
|
15
|
-
export function makeLerpSmoother(animator: import("../utils/animator.js").default, callback: (value:
|
|
16
|
+
export function makeLerpSmoother<T extends Record<string, number>>(animator: import("../utils/animator.js").default, callback: (value: T) => void, halfLife: number, stopAt: number, initialValue: T): ((target: T) => void) & {
|
|
17
|
+
stop: () => void;
|
|
18
|
+
};
|
|
16
19
|
export default class Animator {
|
|
17
20
|
/**
|
|
18
21
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../../src/utils/animator.js"],"names":[],"mappings":"AAoFA
|
|
1
|
+
{"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../../src/utils/animator.js"],"names":[],"mappings":"AAoFA;;;;;;;;;;;;;;GAcG;AACH,6EARW,OAAO,sBAAsB,EAAE,OAAO,0BACxB,IAAI,YAClB,MAAM,UACN,MAAM,oCAEY,IAAI;UAAY,MAAM,IAAI;EAgFtD;AA9KD;IACI;;;OAGG;IACH,mCAFoB,MAAM,KAAE,IAAI,EAS/B;IANG,wBAHgB,MAAM,KAAE,IAAI,CAGS;IACrC,0BAA6B;IAC7B,eAAkB;IAElB,wCAAwC;IACxC,aADW,QAAU,MAAM,KAAE,IAAI,CAAC,EAAE,CACf;IAGzB;;;;;;;;;OASG;IACH,mCAFoB,MAAM,KAAE,IAAI,QAM/B;IAED;;OAEG;IACH,kCAFoB,MAAM,KAAE,IAAI,QAO/B;IAED;;;;OAIG;IACH,sBAoBC;IAED;;;;;OAKG;IACH,oBAFW,OAAO,iBAAiB,EAAE,iBAAiB,gBAQrD;CACJ"}
|
|
@@ -90,44 +90,64 @@ export default class Animator {
|
|
|
90
90
|
* Read more at: https://www.gamedeveloper.com/programming/improved-lerp-smoothing-
|
|
91
91
|
*
|
|
92
92
|
* @param {import("../utils/animator.js").default} animator
|
|
93
|
-
* @param {(value:
|
|
93
|
+
* @param {(value: T) => void} callback Function to be called with the interpolated value
|
|
94
94
|
* @param {number} halfLife Time until half of the value is reached, in milliseconds
|
|
95
95
|
* @param {number} stopAt Stop animation when the value is within this distance from the target
|
|
96
|
-
* @param {
|
|
97
|
-
* @returns {(target:
|
|
96
|
+
* @param {T} initialValue Initial value
|
|
97
|
+
* @returns {((target: T) => void) & { stop: () => void}} Function that activates the transition with a new target value
|
|
98
|
+
* @template {Record<string, number>} T
|
|
98
99
|
*/
|
|
99
100
|
export function makeLerpSmoother(
|
|
100
101
|
animator,
|
|
101
102
|
callback,
|
|
102
103
|
halfLife,
|
|
103
104
|
stopAt,
|
|
104
|
-
initialValue
|
|
105
|
+
initialValue
|
|
105
106
|
) {
|
|
106
107
|
let lastTimeStamp = 0;
|
|
107
108
|
let settled = true;
|
|
108
109
|
|
|
109
|
-
let current = initialValue;
|
|
110
|
+
let current = structuredClone(initialValue);
|
|
110
111
|
let target = current;
|
|
111
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Smoother for a scalar.
|
|
115
|
+
* Based on: https://twitter.com/FreyaHolmer/status/1757836988495847568
|
|
116
|
+
*
|
|
117
|
+
* @param {number} current
|
|
118
|
+
* @param {number} target
|
|
119
|
+
* @param {number} tD
|
|
120
|
+
* @param {number} halfLife
|
|
121
|
+
*/
|
|
122
|
+
function lerpSmooth(current, target, tD, halfLife) {
|
|
123
|
+
return target + (current - target) * Math.pow(2, -tD / halfLife);
|
|
124
|
+
}
|
|
125
|
+
|
|
112
126
|
/**
|
|
113
127
|
* @param {number} [timestamp]
|
|
114
128
|
*/
|
|
115
129
|
function smoothUpdate(timestamp) {
|
|
116
|
-
|
|
130
|
+
if (settled) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
117
133
|
|
|
118
|
-
|
|
119
|
-
// wait until the next frame to get a proper time delta.
|
|
120
|
-
const tD = settled ? 0 : timestamp - lastTimeStamp;
|
|
134
|
+
const tD = timestamp - lastTimeStamp;
|
|
121
135
|
lastTimeStamp = timestamp;
|
|
122
136
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
for (const key of /** @type {(keyof T)[]} */ (Object.keys(target))) {
|
|
138
|
+
current[key] = /** @type {T[keyof T]}*/ (
|
|
139
|
+
lerpSmooth(current[key], target[key], tD, halfLife)
|
|
140
|
+
);
|
|
141
|
+
}
|
|
127
142
|
|
|
128
143
|
callback(current);
|
|
129
144
|
|
|
130
|
-
|
|
145
|
+
let maxDiff = -Infinity;
|
|
146
|
+
for (const key of Object.keys(target)) {
|
|
147
|
+
maxDiff = Math.max(maxDiff, Math.abs(target[key] - current[key]));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (maxDiff < stopAt) {
|
|
131
151
|
current = target;
|
|
132
152
|
callback(current);
|
|
133
153
|
settled = true;
|
|
@@ -138,12 +158,20 @@ export function makeLerpSmoother(
|
|
|
138
158
|
}
|
|
139
159
|
|
|
140
160
|
/**
|
|
141
|
-
* @param {
|
|
161
|
+
* @param {T} value
|
|
142
162
|
*/
|
|
143
|
-
|
|
163
|
+
function setTarget(value) {
|
|
144
164
|
target = value;
|
|
145
165
|
if (settled) {
|
|
146
|
-
|
|
166
|
+
settled = false;
|
|
167
|
+
lastTimeStamp = +document.timeline.currentTime;
|
|
168
|
+
smoothUpdate(lastTimeStamp);
|
|
147
169
|
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
setTarget.stop = () => {
|
|
173
|
+
settled = true;
|
|
148
174
|
};
|
|
175
|
+
|
|
176
|
+
return setTarget;
|
|
149
177
|
}
|
|
@@ -19,7 +19,11 @@ export default class Inertia {
|
|
|
19
19
|
callback: (arg0: number) => void;
|
|
20
20
|
targetValue: number;
|
|
21
21
|
lastValue: number;
|
|
22
|
-
smoother: (target:
|
|
22
|
+
smoother: ((target: {
|
|
23
|
+
x: number;
|
|
24
|
+
}) => void) & {
|
|
25
|
+
stop: () => void;
|
|
26
|
+
};
|
|
23
27
|
cancel(): void;
|
|
24
28
|
/**
|
|
25
29
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inertia.d.ts","sourceRoot":"","sources":["../../../src/utils/inertia.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inertia.d.ts","sourceRoot":"","sources":["../../../src/utils/inertia.js"],"names":[],"mappings":"AAoEA;;;GAGG;AACH,8EAiBC;AArFD;;GAEG;AACH;IACI;;;OAGG;IACH,sBAHW,OAAO,eAAe,EAAE,OAAO,aAC/B,OAAO,EA0BjB;IAvBG,0CAAwB;IACxB,kBAA0B;IAG1B,oBAAsB;IAEtB,oCAAoC;IACpC,iBADoB,MAAM,KAAE,IAAI,CACZ;IAEpB,oBAAoB;IACpB,kBAAkB;IAElB;;;;MAUC;IAGL,eAIC;IAED;;;;OAIG;IACH,mBAHW,MAAM,mBACG,MAAM,KAAE,IAAI,QAkB/B;CACJ"}
|
|
@@ -26,19 +26,20 @@ export default class Inertia {
|
|
|
26
26
|
this.smoother = makeLerpSmoother(
|
|
27
27
|
animator,
|
|
28
28
|
(value) => {
|
|
29
|
-
const delta = value - this.lastValue;
|
|
30
|
-
this.lastValue = value;
|
|
29
|
+
const delta = value.x - this.lastValue;
|
|
30
|
+
this.lastValue = value.x;
|
|
31
31
|
this.callback?.(delta);
|
|
32
32
|
},
|
|
33
33
|
40,
|
|
34
|
-
0.1
|
|
34
|
+
0.1,
|
|
35
|
+
{ x: 0 }
|
|
35
36
|
);
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
cancel() {
|
|
39
40
|
// decelelerate rapidly
|
|
40
41
|
this.targetValue = lerp([this.lastValue, this.targetValue], 0.3);
|
|
41
|
-
this.smoother(this.targetValue);
|
|
42
|
+
this.smoother({ x: this.targetValue });
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -61,7 +62,7 @@ export default class Inertia {
|
|
|
61
62
|
);
|
|
62
63
|
this.targetValue = this.lastValue + delta;
|
|
63
64
|
|
|
64
|
-
this.smoother(this.targetValue);
|
|
65
|
+
this.smoother({ x: this.targetValue });
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
*/
|
|
4
|
+
export default class RingBuffer<T> {
|
|
5
|
+
/**
|
|
6
|
+
* @param {number} size
|
|
7
|
+
*/
|
|
8
|
+
constructor(size: number);
|
|
9
|
+
/** @param {T} value */
|
|
10
|
+
push(value: T): void;
|
|
11
|
+
/**
|
|
12
|
+
* @returns {T[]}
|
|
13
|
+
*/
|
|
14
|
+
get(): T[];
|
|
15
|
+
get size(): number;
|
|
16
|
+
get length(): number;
|
|
17
|
+
#private;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ringBuffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ringBuffer.d.ts","sourceRoot":"","sources":["../../../src/utils/ringBuffer.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;IAQI;;OAEG;IACH,kBAFW,MAAM,EAIhB;IAED,uBAAuB;IACvB,YADY,CAAC,QAKZ;IAED;;OAEG;IACH,OAFa,CAAC,EAAE,CAOf;IAED,mBAEC;IAED,qBAEC;;CACJ"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
*/
|
|
4
|
+
export default class RingBuffer {
|
|
5
|
+
/** @type {T[]} */
|
|
6
|
+
#buffer;
|
|
7
|
+
|
|
8
|
+
#index = 0;
|
|
9
|
+
|
|
10
|
+
#length = 0;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {number} size
|
|
14
|
+
*/
|
|
15
|
+
constructor(size) {
|
|
16
|
+
this.#buffer = new Array(size);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** @param {T} value */
|
|
20
|
+
push(value) {
|
|
21
|
+
this.#buffer[this.#index] = value;
|
|
22
|
+
this.#index = (this.#index + 1) % this.size;
|
|
23
|
+
this.#length = Math.min(this.#length + 1, this.size);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @returns {T[]}
|
|
28
|
+
*/
|
|
29
|
+
get() {
|
|
30
|
+
const b = this.#buffer;
|
|
31
|
+
return this.#length < this.size
|
|
32
|
+
? b.slice(0, this.#length)
|
|
33
|
+
: b.slice(this.#index, this.size).concat(b.slice(0, this.#index));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get size() {
|
|
37
|
+
return this.#buffer.length;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get length() {
|
|
41
|
+
return this.#length;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import RingBuffer from "./ringBuffer.js";
|
|
3
|
+
|
|
4
|
+
describe("ringBuffer", () => {
|
|
5
|
+
test("Empty buffer", () => {
|
|
6
|
+
const buffer = new RingBuffer(10);
|
|
7
|
+
expect(buffer.length).toBe(0);
|
|
8
|
+
expect(buffer.get()).toEqual([]);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("Partially filled buffer", () => {
|
|
12
|
+
const buffer = new RingBuffer(10);
|
|
13
|
+
buffer.push(1);
|
|
14
|
+
buffer.push(2);
|
|
15
|
+
buffer.push(3);
|
|
16
|
+
expect(buffer.length).toBe(3);
|
|
17
|
+
expect(buffer.get()).toEqual([1, 2, 3]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("Full buffer", () => {
|
|
21
|
+
const buffer = new RingBuffer(3);
|
|
22
|
+
buffer.push(1);
|
|
23
|
+
buffer.push(2);
|
|
24
|
+
buffer.push(3);
|
|
25
|
+
expect(buffer.length).toBe(3);
|
|
26
|
+
expect(buffer.get()).toEqual([1, 2, 3]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("Overfilled buffer", () => {
|
|
30
|
+
const buffer = new RingBuffer(3);
|
|
31
|
+
buffer.push(1);
|
|
32
|
+
buffer.push(2);
|
|
33
|
+
buffer.push(3);
|
|
34
|
+
buffer.push(4);
|
|
35
|
+
buffer.push(5);
|
|
36
|
+
expect(buffer.length).toBe(3);
|
|
37
|
+
expect(buffer.get()).toEqual([3, 4, 5]);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -122,7 +122,11 @@ declare class Scrollbar extends UnitView {
|
|
|
122
122
|
scrollbarSize: number;
|
|
123
123
|
scrollbarPadding: number;
|
|
124
124
|
};
|
|
125
|
-
interpolateViewportOffset: (target:
|
|
125
|
+
interpolateViewportOffset: ((target: {
|
|
126
|
+
x: number;
|
|
127
|
+
}) => void) & {
|
|
128
|
+
stop: () => void;
|
|
129
|
+
};
|
|
126
130
|
get scrollOffset(): number;
|
|
127
131
|
/**
|
|
128
132
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../src/view/gridView.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gridView.d.ts","sourceRoot":"","sources":["../../../src/view/gridView.js"],"names":[],"mappings":"AAswBA;;;GAGG;AACH,iDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CAwB9C;AAED;;;GAGG;AACH,uDAHW,OAAO,iBAAiB,EAAE,cAAc,GACtC,OAAO,iBAAiB,EAAE,QAAQ,CA6C9C;AA2BD;;GAEG;AACH,8EAUC;AAED;;;;;GAKG;AACH,4CAJW,OAAO,uBAAuB,EAAE,OAAO,UACvC,OAAO,iBAAiB,EAAE,UAAU,YACpC,QAAQ,aAmBlB;AA53BD;;;;;;;;;;;;;;;GAeG;AACH;IA6BI;;;;;;;;;OASG;IACH,kBARW,OAAO,iBAAiB,EAAE,aAAa,WACvC,OAAO,yBAAyB,EAAE,OAAO,gBACzC,aAAa,iDAEb,MAAM,WACN,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAoBzC;IARG,8CAAgB;IAOhB,uBAA0B;IAG9B;;OAEG;IACH,qDAIC;IAeD;;OAEG;IACH,wDAKC;IAqBD;;OAEG;IACH,8CAEC;IAED,yBAEC;IAED;;OAEG;IACH,wCAmCC;IA2OD;;;;OAIG;IAEH,gBALW,OAAO,4CAA4C,EAAE,OAAO,UAC5D,OAAO,uBAAuB,EAAE,OAAO,YACvC,OAAO,uBAAuB,EAAE,gBAAgB,QA6O1D;;CAoGJ;AAgJD;IACI;;;;OAIG;IACH,6DAHW,aAAa,UACb,MAAM,EAoFhB;IAjFG,4BAAgC;IAChC,kCAAgB;IAChB,eAAoB;IAEpB,uBAAuB;IACvB,YADW,QAAQ,CACQ;IAE3B,uBAAuB;IACvB,kBADW,QAAQ,CACc;IAEjC,mFAAmF;IACnF,MADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAC5D;IAEd,4FAA4F;IAC5F,WADW,QAAQ,OAAO,OAAO,iBAAiB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAC3D;IAEnB,0DAA0D;IAC1D,kEAAoB;IAEpB,uBAAuB;IACvB,OADW,QAAQ,CACG;IAEtB,wBAAwB;IACxB,QADW,SAAS,CACQ;IA4DhC,uEAcC;IAED;;OAEG;IACH,4BAkKC;IAED,uBAqBC;IAED,iCAEC;CACJ;qBAlrC0D,eAAe;sBAFpD,uBAAuB;0BAGnB,oBAAoB;qBAGzB,eAAe;yBALX,mBAAmB;AAqrC5C;IAeI;;;OAGG;IACH,uBAHW,SAAS,8CA6FnB;IAhGD,uBAAmB;IAsCf;;;MAAoB;IAIpB;;;;MAQC;IAgDL,2BAKC;IAWD;;;;OAIG;IACH,gCAHW,SAAS,UACT,SAAS,QA8CnB;;CACJ;oBAx2CmB,qBAAqB"}
|
|
@@ -16,7 +16,7 @@ import ContainerView from "./containerView.js";
|
|
|
16
16
|
import LayerView from "./layerView.js";
|
|
17
17
|
import createTitle from "./title.js";
|
|
18
18
|
import UnitView from "./unitView.js";
|
|
19
|
-
import interactionToZoom from "./zoom.js";
|
|
19
|
+
import { interactionToZoom } from "./zoom.js";
|
|
20
20
|
import clamp from "../utils/clamp.js";
|
|
21
21
|
import { makeLerpSmoother } from "../utils/animator.js";
|
|
22
22
|
|
|
@@ -712,7 +712,8 @@ export default class GridView extends ContainerView {
|
|
|
712
712
|
pointedChild.view,
|
|
713
713
|
zoomEvent
|
|
714
714
|
),
|
|
715
|
-
this.context.getCurrentHover()
|
|
715
|
+
this.context.getCurrentHover(),
|
|
716
|
+
this.context.animator
|
|
716
717
|
);
|
|
717
718
|
}
|
|
718
719
|
}
|
|
@@ -1272,11 +1273,11 @@ class Scrollbar extends UnitView {
|
|
|
1272
1273
|
this.interpolateViewportOffset = makeLerpSmoother(
|
|
1273
1274
|
this.context.animator,
|
|
1274
1275
|
(value) => {
|
|
1275
|
-
this.viewportOffset = value;
|
|
1276
|
+
this.viewportOffset = value.x;
|
|
1276
1277
|
},
|
|
1277
1278
|
50,
|
|
1278
1279
|
0.4,
|
|
1279
|
-
this.viewportOffset
|
|
1280
|
+
{ x: this.viewportOffset }
|
|
1280
1281
|
);
|
|
1281
1282
|
|
|
1282
1283
|
this.addInteractionEventListener("mousedown", (coords, event) => {
|
|
@@ -1308,10 +1309,11 @@ class Scrollbar extends UnitView {
|
|
|
1308
1309
|
this.#maxScrollOffset
|
|
1309
1310
|
);
|
|
1310
1311
|
|
|
1311
|
-
this.interpolateViewportOffset(
|
|
1312
|
-
|
|
1313
|
-
this.#
|
|
1314
|
-
|
|
1312
|
+
this.interpolateViewportOffset({
|
|
1313
|
+
x:
|
|
1314
|
+
(scrollOffset / this.#maxScrollOffset) *
|
|
1315
|
+
this.#maxViewportOffset,
|
|
1316
|
+
});
|
|
1315
1317
|
};
|
|
1316
1318
|
|
|
1317
1319
|
const onMouseup = () => {
|