@sswroom/sswr 1.6.20 → 1.6.22
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/Changelog +25 -0
- package/cesium.d.ts +13 -5
- package/cesium.js +225 -21
- package/data.d.ts +3 -0
- package/data.js +94 -1
- package/domtoimage/images.js +5 -3
- package/domtoimage/index.js +18 -13
- package/domtoimage/inliner.js +9 -7
- package/domtoimage/util.js +0 -106
- package/dummy/olayer2.d.ts +1 -1
- package/leaflet/EasyPrint.js +73 -65
- package/leaflet.d.ts +10 -4
- package/leaflet.js +258 -16
- package/map.d.ts +39 -29
- package/olayer2.d.ts +10 -4
- package/olayer2.js +82 -3
- package/package.json +1 -1
- package/parser.js +20 -0
- package/text.d.ts +3 -0
- package/text.js +24 -0
- package/web.d.ts +18 -0
- package/web.js +100 -0
package/Changelog
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
1.6.22
|
|
2
|
+
-Enhance map.MapControl Marker
|
|
3
|
+
-Added map.MapControl.layerMoveMarker
|
|
4
|
+
-Added map.MapControl.markerUpdateIcon
|
|
5
|
+
-Added map.MapControl.markerShowPopup
|
|
6
|
+
-Added map.MapControl.hidePopup
|
|
7
|
+
-Added map.MapControl.sizeUpdated
|
|
8
|
+
-Added cesium.parseColor
|
|
9
|
+
-Enhance cesium and leaflet map
|
|
10
|
+
|
|
11
|
+
1.6.21
|
|
12
|
+
-Added data.dataURI2Blob
|
|
13
|
+
-Added EasyPrint.toSVG
|
|
14
|
+
-Added data.blob2DataURL
|
|
15
|
+
-Added data.fetchAsBlob
|
|
16
|
+
-Added text.isDataURL
|
|
17
|
+
-Added text.escapeXhtml
|
|
18
|
+
-Added text.svgStringToDataURI
|
|
19
|
+
-Added web.canvasToBlob
|
|
20
|
+
-Added web.elementToSVGString
|
|
21
|
+
-Added web.genPrintWindowHTML
|
|
22
|
+
-Added web.printImageData
|
|
23
|
+
-Added cesium.CesiumMap.getViewer
|
|
24
|
+
-parser support PNG without EXIF
|
|
25
|
+
|
|
1
26
|
1.6.20
|
|
2
27
|
-Enhance XLSXExporter
|
|
3
28
|
-Added leaflet/EasyPrint.js
|
package/cesium.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as geometry from "./geometry";
|
|
|
3
3
|
import * as kml from "./kml";
|
|
4
4
|
import * as map from "./map";
|
|
5
5
|
import * as math from "./math";
|
|
6
|
+
import * as web from "./web";
|
|
6
7
|
|
|
7
8
|
declare class KMLFeatureOptions
|
|
8
9
|
{
|
|
@@ -18,10 +19,12 @@ export function fromCartesian3Array(viewer: Viewer, arr: Cartesian3[]): object[]
|
|
|
18
19
|
export function fromPolygonGraphics(viewer: Viewer, pg: PolygonGraphics): geometry.Polygon;
|
|
19
20
|
export function createFromKML(feature: kml.Feature | kml.KMLFile, options: KMLFeatureOptions): any;
|
|
20
21
|
export function createFromGeometry(geom: geometry.Vector2D, options: map.GeometryOptions)
|
|
21
|
-
|
|
22
|
+
export function parseColor(c: string): web.Color;
|
|
22
23
|
export class CesiumMap extends map.MapControl
|
|
23
24
|
{
|
|
24
25
|
constructor(divId: string);
|
|
26
|
+
getDiv(): HTMLDivElement;
|
|
27
|
+
sizeUpdated(): void;
|
|
25
28
|
createLayer(layer: map.LayerInfo, options?: map.LayerOptions): any;
|
|
26
29
|
createMarkerLayer(name: string, options?: map.LayerOptions): any;
|
|
27
30
|
createGeometryLayer(name: string, options?: map.LayerOptions): any;
|
|
@@ -40,14 +43,19 @@ export class CesiumMap extends map.MapControl
|
|
|
40
43
|
map2ScnPos(mapPos: math.Coord2D): math.Coord2D;
|
|
41
44
|
scn2MapPos(scnPos: math.Coord2D): math.Coord2D;
|
|
42
45
|
|
|
43
|
-
createMarker(mapPos: math.Coord2D, imgURL: string, imgWidth: number, imgHeight: number, options?: map.MarkerOptions):
|
|
44
|
-
layerAddMarker(markerLayer: any, marker:
|
|
45
|
-
layerRemoveMarker(markerLayer: any, marker:
|
|
46
|
+
createMarker(mapPos: math.Coord2D, imgURL: string, imgWidth: number, imgHeight: number, options?: map.MarkerOptions): map.MarkerInfo;
|
|
47
|
+
layerAddMarker(markerLayer: any, marker: map.MarkerInfo): void;
|
|
48
|
+
layerRemoveMarker(markerLayer: any, marker: map.MarkerInfo): void;
|
|
46
49
|
layerClearMarkers(markerLayer: any): void;
|
|
47
|
-
|
|
50
|
+
layerMoveMarker(markerLayer: any, marker: MarkerInfo, mapPos: math.Coord2D): MarkerInfo;
|
|
51
|
+
markerUpdateIcon(markerLayer: any, marker: MarkerInfo, url: string): MarkerInfo;
|
|
52
|
+
markerIsOver(marker: map.MarkerInfo, scnPos: math.Coord2D): boolean;
|
|
53
|
+
markerShowPopup(marker: MarkerInfo, content: string, w?: number, h?: number): void;
|
|
54
|
+
hidePopup();
|
|
48
55
|
|
|
49
56
|
createGeometry(geom: geometry.Vector2D, options: map.GeometryOptions): any;
|
|
50
57
|
layerAddGeometry(geometryLayer: any, geom: any): void;
|
|
51
58
|
layerRemoveGeometry(geometryLayer: any, geom: any): void;
|
|
52
59
|
layerClearGeometries(geometryLayer: any): void;
|
|
60
|
+
getViewer(): Viewer;
|
|
53
61
|
}
|
package/cesium.js
CHANGED
|
@@ -4,7 +4,14 @@ import * as kml from "./kml.js";
|
|
|
4
4
|
import * as map from "./map.js";
|
|
5
5
|
import * as math from "./math.js";
|
|
6
6
|
import * as text from "./text.js";
|
|
7
|
+
import * as web from "./web.js";
|
|
7
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @param {{ scene: { globe: { ellipsoid: any; }; }; camera: { pickEllipsoid: (arg0: any, arg1: any) => any; }; }} viewer
|
|
11
|
+
* @param {number} x
|
|
12
|
+
* @param {number} y
|
|
13
|
+
* @param {{ cartesianToCartographic: (arg0: any) => any; } | null} ellipsoid
|
|
14
|
+
*/
|
|
8
15
|
export function screenToLatLon(viewer, x, y, ellipsoid)
|
|
9
16
|
{
|
|
10
17
|
let pos = new Cesium.Cartesian2(x, y);
|
|
@@ -258,6 +265,10 @@ export function createFromKML(feature, options)
|
|
|
258
265
|
}
|
|
259
266
|
}
|
|
260
267
|
|
|
268
|
+
/**
|
|
269
|
+
* @param {geometry.Vector2D} geom
|
|
270
|
+
* @param {map.GeometryOptions} options
|
|
271
|
+
*/
|
|
261
272
|
export function createFromGeometry(geom, options)
|
|
262
273
|
{
|
|
263
274
|
if (geom instanceof geometry.Point)
|
|
@@ -278,12 +289,40 @@ export function createFromGeometry(geom, options)
|
|
|
278
289
|
position: Cesium.Cartesian3.fromDegrees(geom.coordinates[0], geom.coordinates[1]),
|
|
279
290
|
billboard: new Cesium.BillboardGraphics(opt)});
|
|
280
291
|
}
|
|
292
|
+
else if (geom instanceof geometry.LinearRing)
|
|
293
|
+
{
|
|
294
|
+
let opt = {};
|
|
295
|
+
opt.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
|
|
296
|
+
opt.height = 0;
|
|
297
|
+
if (options.lineColor)
|
|
298
|
+
{
|
|
299
|
+
let c = parseColor(options.lineColor);
|
|
300
|
+
opt.outlineColor = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
301
|
+
opt.outline = true;
|
|
302
|
+
}
|
|
303
|
+
if (options.lineWidth)
|
|
304
|
+
{
|
|
305
|
+
opt.outlineWidth = options.lineWidth;
|
|
306
|
+
opt.outline = true;
|
|
307
|
+
}
|
|
308
|
+
if (options.fillColor)
|
|
309
|
+
{
|
|
310
|
+
let c = parseColor(options.fillColor);
|
|
311
|
+
if (options.fillOpacity)
|
|
312
|
+
{
|
|
313
|
+
c.a = options.fillOpacity;
|
|
314
|
+
}
|
|
315
|
+
opt.material = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
316
|
+
}
|
|
317
|
+
opt.hierarchy = {positions: toCartesian3Arr(geom.coordinates), holes: []};
|
|
318
|
+
return new Cesium.Entity({polygon: new Cesium.PolygonGraphics(opt)});
|
|
319
|
+
}
|
|
281
320
|
else if (geom instanceof geometry.LineString)
|
|
282
321
|
{
|
|
283
322
|
let opt = {};
|
|
284
323
|
if (options.lineColor)
|
|
285
324
|
{
|
|
286
|
-
let c =
|
|
325
|
+
let c = parseColor(options.lineColor);
|
|
287
326
|
opt.material = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
288
327
|
}
|
|
289
328
|
if (options.lineWidth)
|
|
@@ -298,7 +337,7 @@ export function createFromGeometry(geom, options)
|
|
|
298
337
|
opt.height = 0;
|
|
299
338
|
if (options.lineColor)
|
|
300
339
|
{
|
|
301
|
-
let c =
|
|
340
|
+
let c = parseColor(options.lineColor);
|
|
302
341
|
opt.outlineColor = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
303
342
|
opt.outline = true;
|
|
304
343
|
}
|
|
@@ -309,7 +348,11 @@ export function createFromGeometry(geom, options)
|
|
|
309
348
|
}
|
|
310
349
|
if (options.fillColor)
|
|
311
350
|
{
|
|
312
|
-
let c =
|
|
351
|
+
let c = parseColor(options.fillColor);
|
|
352
|
+
if (options.fillOpacity)
|
|
353
|
+
{
|
|
354
|
+
c.a = options.fillOpacity;
|
|
355
|
+
}
|
|
313
356
|
opt.material = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
314
357
|
}
|
|
315
358
|
opt.hierarchy = {positions: toCartesian3Arr(geom.geometries[0].coordinates), holes: []};
|
|
@@ -331,7 +374,7 @@ export function createFromGeometry(geom, options)
|
|
|
331
374
|
let opt = {};
|
|
332
375
|
if (options.lineColor)
|
|
333
376
|
{
|
|
334
|
-
let c =
|
|
377
|
+
let c = parseColor(options.lineColor);
|
|
335
378
|
opt.outlineColor = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
336
379
|
opt.outline = true;
|
|
337
380
|
}
|
|
@@ -342,7 +385,11 @@ export function createFromGeometry(geom, options)
|
|
|
342
385
|
}
|
|
343
386
|
if (options.fillColor)
|
|
344
387
|
{
|
|
345
|
-
let c =
|
|
388
|
+
let c = parseColor(options.fillColor);
|
|
389
|
+
if (options.fillOpacity)
|
|
390
|
+
{
|
|
391
|
+
c.a = options.fillOpacity;
|
|
392
|
+
}
|
|
346
393
|
opt.material = new Cesium.Color(c.r, c.g, c.b, c.a);
|
|
347
394
|
}
|
|
348
395
|
console.log("MultiPolygon not supported", geom);
|
|
@@ -355,6 +402,19 @@ export function createFromGeometry(geom, options)
|
|
|
355
402
|
}
|
|
356
403
|
}
|
|
357
404
|
|
|
405
|
+
/**
|
|
406
|
+
* @param {string} c
|
|
407
|
+
*/
|
|
408
|
+
export function parseColor(c)
|
|
409
|
+
{
|
|
410
|
+
let col = kml.toColor(c);
|
|
411
|
+
if (col == null)
|
|
412
|
+
{
|
|
413
|
+
col = web.parseCSSColor(c);
|
|
414
|
+
}
|
|
415
|
+
return col;
|
|
416
|
+
}
|
|
417
|
+
|
|
358
418
|
/*export function createPolygon(viewer, lats, lons, height)
|
|
359
419
|
{
|
|
360
420
|
if (lats.length != lons.length)
|
|
@@ -386,6 +446,7 @@ export class CesiumMap extends map.MapControl
|
|
|
386
446
|
constructor(divId)
|
|
387
447
|
{
|
|
388
448
|
super();
|
|
449
|
+
this.mouseMove = null;
|
|
389
450
|
this.viewer = new Cesium.Viewer(divId, {
|
|
390
451
|
timeline:false,
|
|
391
452
|
animation:false,
|
|
@@ -395,8 +456,29 @@ export class CesiumMap extends map.MapControl
|
|
|
395
456
|
// url: "https://tile.openstreetmap.org/"
|
|
396
457
|
// }))}
|
|
397
458
|
});
|
|
459
|
+
this.viewer.screenSpaceEventHandler.setInputAction((movement) => {
|
|
460
|
+
let pos = movement.startPosition;
|
|
461
|
+
let container = this.viewer.container;
|
|
462
|
+
if (pos.x >= 0 && pos.y >= 0 && pos.x < container.offsetWidth && pos.y < container.offsetHeight)
|
|
463
|
+
{
|
|
464
|
+
if (this.mouseMove)
|
|
465
|
+
{
|
|
466
|
+
this.mouseMove(this.scn2MapPos(new math.Coord2D(pos.x, pos.y)));
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
|
398
470
|
};
|
|
399
471
|
|
|
472
|
+
getDiv()
|
|
473
|
+
{
|
|
474
|
+
return this.viewer.container;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
sizeUpdated()
|
|
478
|
+
{
|
|
479
|
+
|
|
480
|
+
}
|
|
481
|
+
|
|
400
482
|
createLayer(layer, options)
|
|
401
483
|
{
|
|
402
484
|
if (layer.type == map.WebMapType.OSMTile)
|
|
@@ -411,8 +493,16 @@ export class CesiumMap extends map.MapControl
|
|
|
411
493
|
}
|
|
412
494
|
}
|
|
413
495
|
|
|
414
|
-
|
|
415
|
-
|
|
496
|
+
createMarkerLayer(name, options)
|
|
497
|
+
{
|
|
498
|
+
return [];
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
createGeometryLayer(name, options)
|
|
502
|
+
{
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
|
|
416
506
|
addLayer(layer)
|
|
417
507
|
{
|
|
418
508
|
if (layer instanceof Cesium.ImageryLayer)
|
|
@@ -481,20 +571,134 @@ export class CesiumMap extends map.MapControl
|
|
|
481
571
|
this.viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(center.x, center.y, xScale), duration:0});
|
|
482
572
|
}
|
|
483
573
|
|
|
484
|
-
/* handleMouseLClick(clickFunc: (mapPos: math.Coord2D, scnPos: math.Coord2D)=>void): void
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
574
|
+
/* handleMouseLClick(clickFunc: (mapPos: math.Coord2D, scnPos: math.Coord2D)=>void): void;*/
|
|
575
|
+
/**
|
|
576
|
+
* @param {(mapPos: math.Coord2D)=>void} moveFunc
|
|
577
|
+
*/
|
|
578
|
+
handleMouseMove(moveFunc)
|
|
579
|
+
{
|
|
580
|
+
this.mouseMove = moveFunc;
|
|
581
|
+
}
|
|
582
|
+
/* handlePosChange(posFunc: (mapPos: math.Coord2D)=>void): void;*/
|
|
583
|
+
/**
|
|
584
|
+
* @param {math.Coord2D} mapPos
|
|
585
|
+
*/
|
|
586
|
+
map2ScnPos(mapPos)
|
|
587
|
+
{
|
|
588
|
+
let pos = Cesium.SceneTransforms.worldToDrawingBufferCoordinates(this.viewer.scene, Cesium.Cartesian3.fromDegrees(mapPos.x, mapPos.y));
|
|
589
|
+
if (pos)
|
|
590
|
+
{
|
|
591
|
+
return new math.Coord2D(pos.x, pos.y);
|
|
592
|
+
}
|
|
593
|
+
else
|
|
594
|
+
{
|
|
595
|
+
return new math.Coord2D(0, 0);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* @param {math.Coord2D} scnPos
|
|
601
|
+
*/
|
|
602
|
+
scn2MapPos(scnPos)
|
|
603
|
+
{
|
|
604
|
+
return screenToLatLon(this.viewer, scnPos.x, scnPos.y, null);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
createMarker(mapPos, imgURL, imgWidth, imgHeight, options)
|
|
608
|
+
{
|
|
609
|
+
return new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(mapPos.x, mapPos.y), billboard: {image: imgURL, width: imgWidth, height: imgHeight}});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
layerAddMarker(markerLayer, marker)
|
|
613
|
+
{
|
|
614
|
+
markerLayer.push(marker);
|
|
615
|
+
this.viewer.entities.add(marker);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
layerRemoveMarker(markerLayer, marker)
|
|
619
|
+
{
|
|
620
|
+
markerLayer.remove(marker);
|
|
621
|
+
this.viewer.entities.remove(marker);
|
|
622
|
+
}
|
|
489
623
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
624
|
+
layerClearMarkers(markerLayer)
|
|
625
|
+
{
|
|
626
|
+
let geom;
|
|
627
|
+
while (geom = markerLayer.pop())
|
|
628
|
+
{
|
|
629
|
+
this.viewer.entities.remove(geom);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
layerMoveMarker(markerLayer, marker, mapPos)
|
|
634
|
+
{
|
|
635
|
+
marker.position = Cesium.Cartesian3.fromDegrees(mapPos.x, mapPos.y);
|
|
636
|
+
return marker;
|
|
637
|
+
}
|
|
495
638
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
639
|
+
markerUpdateIcon(markerLayer, marker, url)
|
|
640
|
+
{
|
|
641
|
+
marker.billboard.image = url;
|
|
642
|
+
return marker;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
markerIsOver(marker, scnPos)
|
|
646
|
+
{
|
|
647
|
+
let latlng = marker.position.getValue();
|
|
648
|
+
let sz = [marker.billboard.width, marker.billboard.height];
|
|
649
|
+
let iconPos = Cesium.SceneTransforms.worldToDrawingBufferCoordinates(this.viewer.scene, latlng);
|
|
650
|
+
if (sz == null)
|
|
651
|
+
return false;
|
|
652
|
+
if ((scnPos.x < iconPos.x - sz[0] * 0.5) || (scnPos.y < iconPos.y - sz[1] * 0.5))
|
|
653
|
+
return false;
|
|
654
|
+
if ((iconPos.x + sz[0] * 0.5 <= scnPos.x) || (iconPos.y + sz[1] * 0.5 <= scnPos.y))
|
|
655
|
+
return false;
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
markerShowPopup(marker, content, w, h)
|
|
660
|
+
{
|
|
661
|
+
marker.description = {getValue: ()=>{return content;}};
|
|
662
|
+
this.viewer.selectedEntity = marker;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
hidePopup()
|
|
666
|
+
{
|
|
667
|
+
this.viewer.selectedEntity = null;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* @param {geometry.Vector2D} geom
|
|
672
|
+
* @param {map.GeometryOptions} options
|
|
673
|
+
*/
|
|
674
|
+
createGeometry(geom, options)
|
|
675
|
+
{
|
|
676
|
+
return createFromGeometry(geom, options);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
layerAddGeometry(geometryLayer, geom)
|
|
680
|
+
{
|
|
681
|
+
geometryLayer.push(geom);
|
|
682
|
+
this.viewer.entities.add(geom);
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
layerRemoveGeometry(geometryLayer, geom)
|
|
686
|
+
{
|
|
687
|
+
geometryLayer.remove(geom);
|
|
688
|
+
this.viewer.entities.remove(geom);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
layerClearGeometries(geometryLayer)
|
|
692
|
+
{
|
|
693
|
+
let geom;
|
|
694
|
+
while (geom = geometryLayer.pop())
|
|
695
|
+
{
|
|
696
|
+
this.viewer.entities.remove(geom);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
getViewer()
|
|
701
|
+
{
|
|
702
|
+
return this.viewer;
|
|
703
|
+
}
|
|
500
704
|
}
|
package/data.d.ts
CHANGED
|
@@ -39,6 +39,9 @@ export function shl32(v: number, n: number): number;
|
|
|
39
39
|
export function sar32(v: number, n: number): number;
|
|
40
40
|
export function shr32(v: number, n: number): number;
|
|
41
41
|
export function objectParseTS(o: object, items: string[]): void;
|
|
42
|
+
export function dataURI2Blob(dataURI: string): Blob;
|
|
43
|
+
export function blob2DataURL(blob: Blob): Promise<string|null>;
|
|
44
|
+
export function fetchAsBlob(url: string, options?: {cacheBust: boolean; imagePlaceholder?: string}): Promise<Blob|null>;
|
|
42
45
|
|
|
43
46
|
export class DateValue
|
|
44
47
|
{
|
package/data.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as data from "./data.js";
|
|
1
2
|
import * as text from "./text.js";
|
|
2
3
|
|
|
3
4
|
export const Weekday = {
|
|
@@ -455,6 +456,98 @@ export function objectParseTS(o, items)
|
|
|
455
456
|
}
|
|
456
457
|
}
|
|
457
458
|
|
|
459
|
+
/**
|
|
460
|
+
* @param {string} dataURI
|
|
461
|
+
*/
|
|
462
|
+
export function dataURI2Blob(dataURI)
|
|
463
|
+
{
|
|
464
|
+
let i = dataURI.indexOf(",");
|
|
465
|
+
let dsp = [dataURI.substring(0, i), dataURI.substring(i + 1)];
|
|
466
|
+
let types = dsp[0].split(':')[1].split(';');
|
|
467
|
+
let mimeString = types[0];
|
|
468
|
+
let ab;
|
|
469
|
+
if (types[1] == "base64")
|
|
470
|
+
{
|
|
471
|
+
let byteString = atob(dsp[1]);
|
|
472
|
+
ab = new ArrayBuffer(byteString.length);
|
|
473
|
+
let dw = new DataView(ab);
|
|
474
|
+
for(let i = 0; i < byteString.length; i++) {
|
|
475
|
+
dw.setUint8(i, byteString.charCodeAt(i));
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
else
|
|
479
|
+
{
|
|
480
|
+
let enc = new TextEncoder();
|
|
481
|
+
ab = enc.encode(dsp[1]);
|
|
482
|
+
}
|
|
483
|
+
return new Blob([ab], {type: mimeString});
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* @param {Blob} blob
|
|
488
|
+
*/
|
|
489
|
+
export function blob2DataURL(blob)
|
|
490
|
+
{
|
|
491
|
+
return new Promise((resolve, reject) => {
|
|
492
|
+
let encoder = new FileReader();
|
|
493
|
+
encoder.onloadend = function () {
|
|
494
|
+
let content = encoder.result;
|
|
495
|
+
if (typeof content == 'string')
|
|
496
|
+
resolve(content);
|
|
497
|
+
else
|
|
498
|
+
{
|
|
499
|
+
console.error("Error in converting to dataURL", content);
|
|
500
|
+
resolve(null);
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
encoder.readAsDataURL(blob);
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @param {string} url
|
|
509
|
+
* @param {{ cacheBust: boolean; imagePlaceholder: string; }} options
|
|
510
|
+
*/
|
|
511
|
+
export async function fetchAsBlob(url, options)
|
|
512
|
+
{
|
|
513
|
+
let TIMEOUT = 30000;
|
|
514
|
+
if(options && options.cacheBust) {
|
|
515
|
+
// Cache bypass so we dont have CORS issues with cached images
|
|
516
|
+
// Source: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache
|
|
517
|
+
url += ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime();
|
|
518
|
+
}
|
|
519
|
+
let placeholder;
|
|
520
|
+
if(options && options.imagePlaceholder) {
|
|
521
|
+
if (text.isDataURL(options.imagePlaceholder))
|
|
522
|
+
{
|
|
523
|
+
placeholder = data.dataURI2Blob(options.imagePlaceholder);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
try
|
|
527
|
+
{
|
|
528
|
+
let req = await fetch(url, {signal: AbortSignal.timeout(TIMEOUT)});
|
|
529
|
+
if (!req.ok)
|
|
530
|
+
{
|
|
531
|
+
if(placeholder) {
|
|
532
|
+
return placeholder;
|
|
533
|
+
} else {
|
|
534
|
+
console.error('Cannot fetch resource: ' + url + ', status: ' + req.status);
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return await req.blob();
|
|
539
|
+
}
|
|
540
|
+
catch (error)
|
|
541
|
+
{
|
|
542
|
+
if(placeholder) {
|
|
543
|
+
return placeholder;
|
|
544
|
+
} else {
|
|
545
|
+
console.error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url, error);
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
458
551
|
export class DateValue
|
|
459
552
|
{
|
|
460
553
|
constructor()
|
|
@@ -2212,7 +2305,7 @@ export class TimeInstant
|
|
|
2212
2305
|
if (typeof ticks == "number")
|
|
2213
2306
|
{
|
|
2214
2307
|
secs = Math.floor(ticks / 1000);
|
|
2215
|
-
ms =
|
|
2308
|
+
ms = ticks - (secs * 1000);
|
|
2216
2309
|
secs = BigInt(secs);
|
|
2217
2310
|
}
|
|
2218
2311
|
else
|
package/domtoimage/images.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as data from "../data.js";
|
|
2
|
+
import * as text from "../text.js";
|
|
1
3
|
import * as util from "./util.js";
|
|
2
4
|
import * as inliner from "./inliner.js";
|
|
3
5
|
|
|
@@ -7,9 +9,9 @@ import * as inliner from "./inliner.js";
|
|
|
7
9
|
* @returns {Promise<HTMLImageElement>}
|
|
8
10
|
*/
|
|
9
11
|
async function inline(element, options) {
|
|
10
|
-
if (
|
|
11
|
-
let
|
|
12
|
-
let dataUrl =
|
|
12
|
+
if (text.isDataURL(element.src)) return element;
|
|
13
|
+
let blob = await data.fetchAsBlob(element.src, options);
|
|
14
|
+
let dataUrl = await data.blob2DataURL(blob);
|
|
13
15
|
return await new Promise(function (resolve, reject) {
|
|
14
16
|
element.onload = () => {resolve(element);};
|
|
15
17
|
element.onerror = reject;
|
package/domtoimage/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as text from "../text.js";
|
|
2
|
+
import * as web from "../web.js";
|
|
1
3
|
import * as util from "./util.js";
|
|
2
4
|
import * as images from "./images.js";
|
|
3
5
|
import * as fontFaces from "./fontFaces.js";
|
|
@@ -74,7 +76,7 @@ export async function toPng(node, options) {
|
|
|
74
76
|
* */
|
|
75
77
|
export async function toJpeg(node, options) {
|
|
76
78
|
options = options || {};
|
|
77
|
-
let canvas = await draw(node, options);
|
|
79
|
+
let canvas = await draw(node, options || {});
|
|
78
80
|
return canvas.toDataURL('image/jpeg', options.quality || 1.0);
|
|
79
81
|
}
|
|
80
82
|
|
|
@@ -84,7 +86,7 @@ export async function toJpeg(node, options) {
|
|
|
84
86
|
* */
|
|
85
87
|
export async function toBlob(node, options) {
|
|
86
88
|
let canvas = await draw(node, options || {});
|
|
87
|
-
return await
|
|
89
|
+
return await web.canvasToBlob(canvas);
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
/**
|
|
@@ -109,21 +111,27 @@ function copyOptions(options) {
|
|
|
109
111
|
|
|
110
112
|
/**
|
|
111
113
|
* @param {HTMLElement} domNode
|
|
112
|
-
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}
|
|
114
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}} options
|
|
113
115
|
*/
|
|
114
116
|
async function draw(domNode, options) {
|
|
115
117
|
let svgUrl = await toSvg(domNode, options);
|
|
116
118
|
let image = await util.makeImage(svgUrl);
|
|
117
|
-
await util.delay(100)();
|
|
118
119
|
let canvas = newCanvas(domNode, options);
|
|
119
120
|
let ctx = canvas.getContext('2d');
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
return await new Promise((resolve, reject) => {
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
if (ctx)
|
|
124
|
+
{
|
|
125
|
+
ctx.drawImage(image, 0, 0);
|
|
126
|
+
}
|
|
127
|
+
resolve(canvas);
|
|
128
|
+
}, 1);
|
|
129
|
+
});
|
|
122
130
|
}
|
|
123
131
|
|
|
124
132
|
/**
|
|
125
133
|
* @param {HTMLElement} domNode
|
|
126
|
-
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}
|
|
134
|
+
* @param {{filter?:(node: Node)=>boolean,bgcolor?:string,width?:number,height?:number,style?:{[n:string]:string},quality?:number,imagePlaceholder?:string,cacheBust?:boolean}} options
|
|
127
135
|
*/
|
|
128
136
|
function newCanvas(domNode, options) {
|
|
129
137
|
let canvas = document.createElement('canvas');
|
|
@@ -131,9 +139,10 @@ function newCanvas(domNode, options) {
|
|
|
131
139
|
canvas.height = options.height || domNode.offsetHeight;
|
|
132
140
|
|
|
133
141
|
if (options.bgcolor) {
|
|
134
|
-
|
|
142
|
+
let ctx = canvas.getContext('2d');
|
|
135
143
|
if (ctx != null)
|
|
136
144
|
{
|
|
145
|
+
ctx.globalAlpha = 1;
|
|
137
146
|
ctx.fillStyle = options.bgcolor;
|
|
138
147
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
139
148
|
}
|
|
@@ -320,9 +329,5 @@ async function inlineImages(node, implOptions) {
|
|
|
320
329
|
* @param {string | number} height
|
|
321
330
|
*/
|
|
322
331
|
function makeSvgDataUri(node, width, height) {
|
|
323
|
-
|
|
324
|
-
let xhtml = util.escapeXhtml(new XMLSerializer().serializeToString(node));
|
|
325
|
-
let foreignObject = '<foreignObject x="0" y="0" width="100%" height="100%">' + xhtml + '</foreignObject>';
|
|
326
|
-
let svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '">' + foreignObject + '</svg>';
|
|
327
|
-
return 'data:image/svg+xml;charset=utf-8,' + svg;
|
|
332
|
+
return text.svgStringToDataURI(web.elementToSVGString(node, width, height));
|
|
328
333
|
}
|
package/domtoimage/inliner.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as data from "../data.js";
|
|
2
|
+
import * as text from "../text.js";
|
|
1
3
|
import * as util from "./util.js";
|
|
2
4
|
|
|
3
5
|
let URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g;
|
|
@@ -19,7 +21,7 @@ function readUrls(string) {
|
|
|
19
21
|
result.push(match[1]);
|
|
20
22
|
}
|
|
21
23
|
return result.filter(function (url) {
|
|
22
|
-
return !
|
|
24
|
+
return !text.isDataURL(url);
|
|
23
25
|
});
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -34,24 +36,24 @@ function urlAsRegex(url) {
|
|
|
34
36
|
* @param {string} string
|
|
35
37
|
* @param {string} url
|
|
36
38
|
* @param {string | null | undefined} baseUrl
|
|
37
|
-
* @param {((url: string)=>
|
|
39
|
+
* @param {((url: string)=>Blob)|undefined} get
|
|
38
40
|
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
|
|
39
41
|
*/
|
|
40
42
|
async function inline(string, url, baseUrl, get, options) {
|
|
41
43
|
url = baseUrl ? util.resolveUrl(url, baseUrl) : url;
|
|
42
|
-
let
|
|
44
|
+
let blob;
|
|
43
45
|
if (get)
|
|
44
|
-
|
|
46
|
+
blob = get(url);
|
|
45
47
|
else
|
|
46
|
-
|
|
47
|
-
let dataUrl =
|
|
48
|
+
blob = await data.fetchAsBlob(url, options);
|
|
49
|
+
let dataUrl = await data.blob2DataURL(blob);
|
|
48
50
|
return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3');
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* @param {string} string
|
|
53
55
|
* @param {string | null | undefined} baseUrl
|
|
54
|
-
* @param {((url: string)=>
|
|
56
|
+
* @param {((url: string)=>Blob)|undefined} get
|
|
55
57
|
* @param {{ cacheBust: boolean; imagePlaceholder?: string; } | undefined} options
|
|
56
58
|
*/
|
|
57
59
|
export async function inlineAll(string, baseUrl, get, options) {
|