react-msaview 6.1.1 → 6.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.js +92 -92
- package/bundle/index.js.map +4 -4
- package/dist/components/dialogs/ExportSVGDialog.js +48 -20
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/getVisibleLeaves.d.ts +8 -0
- package/dist/components/getVisibleLeaves.js +13 -6
- package/dist/components/getVisibleLeaves.js.map +1 -1
- package/dist/components/minimap/Minimap.js +1 -1
- package/dist/components/minimap/Minimap.js.map +1 -1
- package/dist/components/minimap/MinimapSVG.d.ts +4 -4
- package/dist/components/minimap/MinimapSVG.js +16 -10
- package/dist/components/minimap/MinimapSVG.js.map +1 -1
- package/dist/components/minimap/minimapLayout.d.ts +5 -8
- package/dist/components/minimap/minimapLayout.js +10 -11
- package/dist/components/minimap/minimapLayout.js.map +1 -1
- package/dist/components/msa/msaRaster.d.ts +32 -2
- package/dist/components/msa/msaRaster.js +93 -15
- package/dist/components/msa/msaRaster.js.map +1 -1
- package/dist/{renderTestEnv.d.ts → headlessRenderEnv.d.ts} +15 -13
- package/dist/{renderTestEnv.js → headlessRenderEnv.js} +22 -18
- package/dist/headlessRenderEnv.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/model.d.ts +25 -0
- package/dist/model.js +62 -13
- package/dist/model.js.map +1 -1
- package/dist/renderToSvg.js +115 -36
- package/dist/renderToSvg.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
- package/src/components/dialogs/ExportSVGDialog.tsx +55 -20
- package/src/components/getVisibleLeaves.ts +25 -9
- package/src/components/minimap/Minimap.tsx +1 -4
- package/src/components/minimap/MinimapSVG.tsx +50 -35
- package/src/components/minimap/minimapLayout.test.ts +16 -5
- package/src/components/minimap/minimapLayout.ts +10 -11
- package/src/components/msa/msaRaster.ts +124 -17
- package/src/{renderTestEnv.ts → headlessRenderEnv.ts} +23 -19
- package/src/impgRender.test.tsx +2 -2
- package/src/index.ts +6 -0
- package/src/model.ts +77 -13
- package/src/modelReset.test.ts +120 -0
- package/src/renderDomainsSvg.test.tsx +2 -2
- package/src/renderMinimapSvg.test.tsx +29 -15
- package/src/renderRasterSvg.test.tsx +216 -0
- package/src/renderSequenceLogoSvg.test.tsx +6 -4
- package/src/renderToSvg.test.tsx +79 -0
- package/src/renderToSvg.tsx +201 -65
- package/src/version.ts +1 -1
- package/dist/renderTestEnv.js.map +0 -1
package/src/renderToSvg.tsx
CHANGED
|
@@ -4,9 +4,12 @@ import React from 'react'
|
|
|
4
4
|
import { renderToStaticMarkup } from '@jbrowse/core/util'
|
|
5
5
|
import { when } from 'mobx'
|
|
6
6
|
|
|
7
|
+
import { visibleRowRange } from './components/getVisibleLeaves.ts'
|
|
7
8
|
import MinimapSVG from './components/minimap/MinimapSVG.tsx'
|
|
9
|
+
import { rasterImageHref, rasterSupported } from './components/msa/msaRaster.ts'
|
|
8
10
|
import { renderBoxFeatureCanvasBlock } from './components/msa/renderBoxFeatureCanvasBlock.ts'
|
|
9
11
|
import { renderMSABlock } from './components/msa/renderMSABlock.ts'
|
|
12
|
+
import { visibleColRange } from './components/msa/visibleColRange.ts'
|
|
10
13
|
import { renderAllTracks } from './components/tracks/drawTracks.ts'
|
|
11
14
|
import { renderTreeCanvas } from './components/tree/renderTreeCanvas.ts'
|
|
12
15
|
import { colorContrast } from './util.ts'
|
|
@@ -30,11 +33,16 @@ const LEGEND_SWATCH = 12
|
|
|
30
33
|
const LEGEND_FONT = 12
|
|
31
34
|
const LEGEND_CHAR_W = 7
|
|
32
35
|
|
|
36
|
+
const LEGEND_MAX_W = 360
|
|
37
|
+
const LEGEND_TEXT_X = LEGEND_PAD + LEGEND_SWATCH + 6
|
|
38
|
+
|
|
33
39
|
function getLegendWidth(model: MsaViewModel) {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
const maxLen = model.visibleDomainTypes.reduce(
|
|
41
|
+
(a, d) => Math.max(a, d.name.length),
|
|
42
|
+
0,
|
|
43
|
+
)
|
|
44
|
+
const w = LEGEND_TEXT_X + LEGEND_PAD + maxLen * LEGEND_CHAR_W
|
|
45
|
+
return Math.min(LEGEND_MAX_W, Math.max(120, w))
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
// resolved sizes/offsets (in svg user units) for the chosen export, shared by
|
|
@@ -42,6 +50,7 @@ function getLegendWidth(model: MsaViewModel) {
|
|
|
42
50
|
// mirrors the live scroll position
|
|
43
51
|
interface Layout {
|
|
44
52
|
width: number
|
|
53
|
+
msaAreaWidth: number
|
|
45
54
|
height: number
|
|
46
55
|
contentHeight: number
|
|
47
56
|
trackHeight: number
|
|
@@ -53,8 +62,6 @@ interface Layout {
|
|
|
53
62
|
|
|
54
63
|
function getLayout(model: MsaViewModel, opts: ExportSvgOptions): Layout {
|
|
55
64
|
const {
|
|
56
|
-
width,
|
|
57
|
-
height,
|
|
58
65
|
scrollX,
|
|
59
66
|
scrollY,
|
|
60
67
|
totalWidth,
|
|
@@ -62,21 +69,33 @@ function getLayout(model: MsaViewModel, opts: ExportSvgOptions): Layout {
|
|
|
62
69
|
treeAreaWidth,
|
|
63
70
|
totalTrackAreaHeight,
|
|
64
71
|
minimapHeight,
|
|
72
|
+
msaAreaHeight,
|
|
73
|
+
msaCanvasWidth,
|
|
74
|
+
showHorizontalScrollbar,
|
|
65
75
|
} = model
|
|
66
76
|
const trackHeight = opts.includeTracks ? totalTrackAreaHeight : 0
|
|
67
77
|
// the minimap reflects the live viewport scroll position, so it's only
|
|
68
|
-
// meaningful for a viewport export, never for the entire alignment
|
|
69
|
-
|
|
78
|
+
// meaningful for a viewport export, never for the entire alignment -- and
|
|
79
|
+
// only when the live view shows one at all, since a minimap over an alignment
|
|
80
|
+
// that already fits marks a viewport wider than the bar
|
|
81
|
+
const includeMinimap =
|
|
82
|
+
opts.exportType === 'viewport' &&
|
|
83
|
+
!!opts.includeMinimap &&
|
|
84
|
+
showHorizontalScrollbar
|
|
70
85
|
const legendWidth =
|
|
71
86
|
model.actuallyShowDomains && model.visibleDomainTypes.length > 0
|
|
72
87
|
? getLegendWidth(model)
|
|
73
88
|
: 0
|
|
74
89
|
|
|
75
|
-
// width stays content-only
|
|
76
|
-
//
|
|
90
|
+
// width stays content-only; the legend occupies an extra column added at the
|
|
91
|
+
// svg root in MsaSvg. The viewport export takes the alignment canvas's own
|
|
92
|
+
// size rather than the widget's -- the widget box also covers the header, the
|
|
93
|
+
// resize handle and the scrollbars, and rendering that box exports rows and
|
|
94
|
+
// columns the scrollbars hide on screen
|
|
77
95
|
return opts.exportType === 'entire'
|
|
78
96
|
? {
|
|
79
97
|
width: totalWidth + treeAreaWidth,
|
|
98
|
+
msaAreaWidth: totalWidth,
|
|
80
99
|
height: totalHeight + trackHeight,
|
|
81
100
|
contentHeight: totalHeight,
|
|
82
101
|
trackHeight,
|
|
@@ -86,9 +105,11 @@ function getLayout(model: MsaViewModel, opts: ExportSvgOptions): Layout {
|
|
|
86
105
|
legendWidth,
|
|
87
106
|
}
|
|
88
107
|
: {
|
|
89
|
-
width,
|
|
90
|
-
|
|
91
|
-
|
|
108
|
+
width: msaCanvasWidth + treeAreaWidth,
|
|
109
|
+
msaAreaWidth: msaCanvasWidth,
|
|
110
|
+
height:
|
|
111
|
+
msaAreaHeight + (includeMinimap ? minimapHeight : 0) + trackHeight,
|
|
112
|
+
contentHeight: msaAreaHeight,
|
|
92
113
|
trackHeight,
|
|
93
114
|
offsetX: -scrollX,
|
|
94
115
|
offsetY: -scrollY,
|
|
@@ -125,26 +146,16 @@ function MsaSvg({
|
|
|
125
146
|
const { treeAreaWidth, minimapHeight } = model
|
|
126
147
|
const totalWidth = width + legendWidth
|
|
127
148
|
const legendTop = includeMinimap ? minimapHeight : 0
|
|
149
|
+
const contrastScheme = colorContrast(model.colorScheme, theme)
|
|
150
|
+
const props = { Context, model, theme, layout, contrastScheme }
|
|
128
151
|
|
|
129
152
|
const body = (
|
|
130
153
|
<>
|
|
131
|
-
{trackHeight > 0 ?
|
|
132
|
-
<TrackRendering
|
|
133
|
-
Context={Context}
|
|
134
|
-
model={model}
|
|
135
|
-
theme={theme}
|
|
136
|
-
layout={layout}
|
|
137
|
-
/>
|
|
138
|
-
) : null}
|
|
154
|
+
{trackHeight > 0 ? <TrackRendering {...props} /> : null}
|
|
139
155
|
<g
|
|
140
156
|
transform={trackHeight > 0 ? `translate(0 ${trackHeight})` : undefined}
|
|
141
157
|
>
|
|
142
|
-
<CoreRendering
|
|
143
|
-
Context={Context}
|
|
144
|
-
model={model}
|
|
145
|
-
theme={theme}
|
|
146
|
-
layout={layout}
|
|
147
|
-
/>
|
|
158
|
+
<CoreRendering {...props} />
|
|
148
159
|
</g>
|
|
149
160
|
</>
|
|
150
161
|
)
|
|
@@ -157,11 +168,18 @@ function MsaSvg({
|
|
|
157
168
|
xmlnsXlink="http://www.w3.org/1999/xlink"
|
|
158
169
|
viewBox={`0 0 ${totalWidth} ${height}`}
|
|
159
170
|
>
|
|
160
|
-
|
|
171
|
+
{/* every layer below draws in the theme's colors, so the page has to be
|
|
172
|
+
the theme's background too -- a hardcoded white one turns a dark-theme
|
|
173
|
+
export into white text on white */}
|
|
174
|
+
<rect
|
|
175
|
+
width="100%"
|
|
176
|
+
height="100%"
|
|
177
|
+
fill={theme.palette.background.default}
|
|
178
|
+
/>
|
|
161
179
|
{includeMinimap ? (
|
|
162
180
|
<>
|
|
163
181
|
<g transform={`translate(${treeAreaWidth} 0)`}>
|
|
164
|
-
<MinimapSVG model={model}
|
|
182
|
+
<MinimapSVG model={model} theme={theme} />
|
|
165
183
|
</g>
|
|
166
184
|
<g transform={`translate(0 ${minimapHeight})`}>{body}</g>
|
|
167
185
|
</>
|
|
@@ -170,7 +188,7 @@ function MsaSvg({
|
|
|
170
188
|
)}
|
|
171
189
|
{legendWidth > 0 ? (
|
|
172
190
|
<g transform={`translate(${width} ${legendTop})`}>
|
|
173
|
-
<LegendSVG model={model} width={legendWidth} />
|
|
191
|
+
<LegendSVG model={model} theme={theme} width={legendWidth} />
|
|
174
192
|
</g>
|
|
175
193
|
) : null}
|
|
176
194
|
</svg>
|
|
@@ -179,9 +197,22 @@ function MsaSvg({
|
|
|
179
197
|
|
|
180
198
|
// the domain color key drawn as a reserved column to the right of the
|
|
181
199
|
// alignment, mirroring the on-screen AnnotationLegend overlay
|
|
182
|
-
function LegendSVG({
|
|
200
|
+
function LegendSVG({
|
|
201
|
+
model,
|
|
202
|
+
theme,
|
|
203
|
+
width,
|
|
204
|
+
}: {
|
|
205
|
+
model: MsaViewModel
|
|
206
|
+
theme: Theme
|
|
207
|
+
width: number
|
|
208
|
+
}) {
|
|
183
209
|
const { visibleDomainTypes, fillPalette, strokePalette } = model
|
|
184
210
|
const boxHeight = LEGEND_PAD * 2 + visibleDomainTypes.length * LEGEND_ROW_H
|
|
211
|
+
// the column is capped at LEGEND_MAX_W, so a name too long for it has to be
|
|
212
|
+
// clipped here -- text that overruns the reserved width runs off the figure
|
|
213
|
+
const maxChars = Math.floor(
|
|
214
|
+
(width - LEGEND_TEXT_X - LEGEND_PAD) / LEGEND_CHAR_W,
|
|
215
|
+
)
|
|
185
216
|
return (
|
|
186
217
|
<g>
|
|
187
218
|
<rect
|
|
@@ -189,7 +220,7 @@ function LegendSVG({ model, width }: { model: MsaViewModel; width: number }) {
|
|
|
189
220
|
y={0}
|
|
190
221
|
width={width - 4}
|
|
191
222
|
height={boxHeight}
|
|
192
|
-
fill=
|
|
223
|
+
fill={theme.palette.background.paper}
|
|
193
224
|
stroke="#ccc"
|
|
194
225
|
rx={2}
|
|
195
226
|
/>
|
|
@@ -206,11 +237,14 @@ function LegendSVG({ model, width }: { model: MsaViewModel; width: number }) {
|
|
|
206
237
|
stroke={strokePalette[d.accession]}
|
|
207
238
|
/>
|
|
208
239
|
<text
|
|
209
|
-
x={
|
|
240
|
+
x={LEGEND_TEXT_X}
|
|
210
241
|
y={y + LEGEND_SWATCH - 1}
|
|
211
242
|
fontSize={LEGEND_FONT}
|
|
243
|
+
fill={theme.palette.text.primary}
|
|
212
244
|
>
|
|
213
|
-
{d.name
|
|
245
|
+
{d.name.length > maxChars
|
|
246
|
+
? `${d.name.slice(0, Math.max(1, maxChars - 1))}…`
|
|
247
|
+
: d.name}
|
|
214
248
|
</text>
|
|
215
249
|
</g>
|
|
216
250
|
)
|
|
@@ -219,21 +253,23 @@ function LegendSVG({ model, width }: { model: MsaViewModel; width: number }) {
|
|
|
219
253
|
)
|
|
220
254
|
}
|
|
221
255
|
|
|
256
|
+
interface LayerProps {
|
|
257
|
+
model: MsaViewModel
|
|
258
|
+
theme: Theme
|
|
259
|
+
layout: Layout
|
|
260
|
+
Context: typeof ContextType
|
|
261
|
+
contrastScheme: Record<string, string>
|
|
262
|
+
}
|
|
263
|
+
|
|
222
264
|
function CoreRendering({
|
|
223
265
|
model,
|
|
224
266
|
theme,
|
|
225
267
|
layout,
|
|
226
268
|
Context,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
Context: typeof ContextType
|
|
232
|
-
}) {
|
|
233
|
-
const { contentHeight, offsetX, offsetY, width } = layout
|
|
234
|
-
const { treeAreaWidth, colorScheme, id } = model
|
|
235
|
-
const msaAreaWidth = width - treeAreaWidth
|
|
236
|
-
const contrastScheme = colorContrast(colorScheme, theme)
|
|
269
|
+
contrastScheme,
|
|
270
|
+
}: LayerProps) {
|
|
271
|
+
const { contentHeight, offsetX, offsetY, msaAreaWidth } = layout
|
|
272
|
+
const { treeAreaWidth, id } = model
|
|
237
273
|
|
|
238
274
|
const treeCtx = new Context(treeAreaWidth, contentHeight)
|
|
239
275
|
renderTreeCanvas({
|
|
@@ -245,6 +281,8 @@ function CoreRendering({
|
|
|
245
281
|
highResScaleFactorOverride: 1,
|
|
246
282
|
})
|
|
247
283
|
|
|
284
|
+
const raster = rasterBackground({ model, theme, layout })
|
|
285
|
+
|
|
248
286
|
const msaCtx = new Context(msaAreaWidth, contentHeight)
|
|
249
287
|
renderBoxFeatureCanvasBlock({
|
|
250
288
|
model,
|
|
@@ -267,6 +305,7 @@ function CoreRendering({
|
|
|
267
305
|
blockSizeXOverride: msaAreaWidth,
|
|
268
306
|
blockSizeYOverride: contentHeight,
|
|
269
307
|
highResScaleFactorOverride: 1,
|
|
308
|
+
rasterTiles: !!raster,
|
|
270
309
|
})
|
|
271
310
|
|
|
272
311
|
return (
|
|
@@ -283,26 +322,79 @@ function CoreRendering({
|
|
|
283
322
|
height={contentHeight}
|
|
284
323
|
transform={`translate(${treeAreaWidth} 0)`}
|
|
285
324
|
ctx={msaCtx}
|
|
325
|
+
underlay={raster}
|
|
286
326
|
/>
|
|
287
327
|
</>
|
|
288
328
|
)
|
|
289
329
|
}
|
|
290
330
|
|
|
291
|
-
|
|
331
|
+
/**
|
|
332
|
+
* The alignment background as a single <image>, on the same terms the live
|
|
333
|
+
* canvas uses it: no domain overlay painting its own boxes, background coloring
|
|
334
|
+
* on, and a canvas we can actually read back.
|
|
335
|
+
*
|
|
336
|
+
* One node replaces the <rect>-per-cell the vector path emits, which is what
|
|
337
|
+
* lets an export of a real alignment finish at all. The image is one pixel per
|
|
338
|
+
* cell drawn across the cells' own rectangle, so it upscales by whole cells --
|
|
339
|
+
* image-rendering keeps those edges hard rather than smearing them, making it
|
|
340
|
+
* pixel-for-pixel what the rects drew.
|
|
341
|
+
*/
|
|
342
|
+
function rasterBackground({
|
|
292
343
|
model,
|
|
293
344
|
theme,
|
|
294
345
|
layout,
|
|
295
|
-
Context,
|
|
296
346
|
}: {
|
|
297
347
|
model: MsaViewModel
|
|
298
348
|
theme: Theme
|
|
299
349
|
layout: Layout
|
|
300
|
-
Context: typeof ContextType
|
|
301
350
|
}) {
|
|
302
|
-
const {
|
|
303
|
-
const {
|
|
304
|
-
|
|
305
|
-
|
|
351
|
+
const { contentHeight, offsetX, offsetY, msaAreaWidth } = layout
|
|
352
|
+
const { colWidth, rowHeight, actuallyShowDomains, bgColor } = model
|
|
353
|
+
if (actuallyShowDomains || !bgColor || !rasterSupported()) {
|
|
354
|
+
return undefined
|
|
355
|
+
}
|
|
356
|
+
const { xStart, xEnd } = visibleColRange({
|
|
357
|
+
offsetX,
|
|
358
|
+
blockWidth: msaAreaWidth,
|
|
359
|
+
colWidth,
|
|
360
|
+
})
|
|
361
|
+
const { yStart, yEnd } = visibleRowRange({
|
|
362
|
+
model,
|
|
363
|
+
offsetY,
|
|
364
|
+
blockSizeY: contentHeight,
|
|
365
|
+
})
|
|
366
|
+
const numCols = Math.min(xEnd, model.numColumns) - xStart
|
|
367
|
+
const numRows = Math.min(yEnd, model.leaves.length) - yStart
|
|
368
|
+
const href = rasterImageHref({
|
|
369
|
+
model,
|
|
370
|
+
theme,
|
|
371
|
+
col0: xStart,
|
|
372
|
+
row0: yStart,
|
|
373
|
+
numCols,
|
|
374
|
+
numRows,
|
|
375
|
+
})
|
|
376
|
+
return href ? (
|
|
377
|
+
<image
|
|
378
|
+
href={href}
|
|
379
|
+
x={xStart * colWidth - offsetX}
|
|
380
|
+
y={yStart * rowHeight - offsetY}
|
|
381
|
+
width={numCols * colWidth}
|
|
382
|
+
height={numRows * rowHeight}
|
|
383
|
+
imageRendering="pixelated"
|
|
384
|
+
preserveAspectRatio="none"
|
|
385
|
+
/>
|
|
386
|
+
) : undefined
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function TrackRendering({
|
|
390
|
+
model,
|
|
391
|
+
theme,
|
|
392
|
+
layout,
|
|
393
|
+
Context,
|
|
394
|
+
contrastScheme,
|
|
395
|
+
}: LayerProps) {
|
|
396
|
+
const { trackHeight, offsetX, msaAreaWidth } = layout
|
|
397
|
+
const { treeAreaWidth, id } = model
|
|
306
398
|
|
|
307
399
|
const ctx = new Context(msaAreaWidth, trackHeight)
|
|
308
400
|
renderAllTracks({
|
|
@@ -316,31 +408,76 @@ function TrackRendering({
|
|
|
316
408
|
})
|
|
317
409
|
|
|
318
410
|
return (
|
|
319
|
-
|
|
320
|
-
<
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
411
|
+
<>
|
|
412
|
+
<TrackLabelsSVG model={model} theme={theme} />
|
|
413
|
+
<g transform={`translate(${treeAreaWidth} 0)`}>
|
|
414
|
+
<ClipGroup
|
|
415
|
+
clipId={`tracks-${id}`}
|
|
416
|
+
width={msaAreaWidth}
|
|
417
|
+
height={trackHeight}
|
|
418
|
+
ctx={ctx}
|
|
419
|
+
/>
|
|
420
|
+
</g>
|
|
421
|
+
</>
|
|
422
|
+
)
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Each track's name in the tree-width column beside it, where the live view puts
|
|
426
|
+
// it (see TrackLabel). Without these the figure has an unlabeled bar chart and
|
|
427
|
+
// an unlabeled logo, and nothing says which is which.
|
|
428
|
+
function TrackLabelsSVG({
|
|
429
|
+
model,
|
|
430
|
+
theme,
|
|
431
|
+
}: {
|
|
432
|
+
model: MsaViewModel
|
|
433
|
+
theme: Theme
|
|
434
|
+
}) {
|
|
435
|
+
const { turnedOnTracks, treeAreaWidth, fontSize, drawLabels } = model
|
|
436
|
+
if (!drawLabels) {
|
|
437
|
+
return null
|
|
438
|
+
}
|
|
439
|
+
let y = 0
|
|
440
|
+
return (
|
|
441
|
+
<>
|
|
442
|
+
{turnedOnTracks.map(track => {
|
|
443
|
+
const { id, name, height } = track.model
|
|
444
|
+
const size = Math.min(height, fontSize)
|
|
445
|
+
const baseline = y + height / 2 + size / 3
|
|
446
|
+
y += height
|
|
447
|
+
return size < 5 ? null : (
|
|
448
|
+
<text
|
|
449
|
+
key={id}
|
|
450
|
+
x={treeAreaWidth - 4}
|
|
451
|
+
y={baseline}
|
|
452
|
+
fontSize={size}
|
|
453
|
+
textAnchor="end"
|
|
454
|
+
fill={theme.palette.text.primary}
|
|
455
|
+
>
|
|
456
|
+
{name}
|
|
457
|
+
</text>
|
|
458
|
+
)
|
|
459
|
+
})}
|
|
460
|
+
</>
|
|
327
461
|
)
|
|
328
462
|
}
|
|
329
463
|
|
|
330
464
|
// Clips a svgcanvas Context to its box and injects its markup verbatim (it is
|
|
331
|
-
// already serialized SVG, not React).
|
|
465
|
+
// already serialized SVG, not React). `underlay` draws beneath that markup,
|
|
466
|
+
// inside the same clip, for the parts of a layer React emits directly.
|
|
332
467
|
function ClipGroup({
|
|
333
468
|
clipId,
|
|
334
469
|
width,
|
|
335
470
|
height,
|
|
336
471
|
transform,
|
|
337
472
|
ctx,
|
|
473
|
+
underlay,
|
|
338
474
|
}: {
|
|
339
475
|
clipId: string
|
|
340
476
|
width: number
|
|
341
477
|
height: number
|
|
342
478
|
transform?: string
|
|
343
479
|
ctx: ContextType
|
|
480
|
+
underlay?: React.ReactNode
|
|
344
481
|
}) {
|
|
345
482
|
return (
|
|
346
483
|
<>
|
|
@@ -349,11 +486,10 @@ function ClipGroup({
|
|
|
349
486
|
<rect x={0} y={0} width={width} height={height} />
|
|
350
487
|
</clipPath>
|
|
351
488
|
</defs>
|
|
352
|
-
<g
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
/>
|
|
489
|
+
<g clipPath={`url(#${clipId})`} transform={transform}>
|
|
490
|
+
{underlay}
|
|
491
|
+
<g dangerouslySetInnerHTML={{ __html: ctx.getSvg().innerHTML }} />
|
|
492
|
+
</g>
|
|
357
493
|
</>
|
|
358
494
|
)
|
|
359
495
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.
|
|
1
|
+
export const version = '6.2.1'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"renderTestEnv.js","sourceRoot":"","sources":["../src/renderTestEnv.ts"],"names":[],"mappings":"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"}
|