snice 4.13.0 → 4.14.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.
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/accordion/snice-accordion.min.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/alert/snice-alert.min.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar/snice-avatar.min.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/badge/snice-badge.min.js +1 -1
- package/dist/cdn/banner/snice-banner.js +1 -1
- package/dist/cdn/banner/snice-banner.min.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/book/snice-book.min.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/button/snice-button.min.js +1 -1
- package/dist/cdn/calendar/snice-calendar.js +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera/snice-camera.min.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.min.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/card/snice-card.min.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/carousel/snice-carousel.min.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chart/snice-chart.min.js +1 -1
- package/dist/cdn/chat/snice-chat.js +1 -1
- package/dist/cdn/chat/snice-chat.min.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/chip/snice-chip.min.js +1 -1
- package/dist/cdn/code-block/snice-code-block.js +2 -2
- package/dist/cdn/code-block/snice-code-block.js.map +1 -1
- package/dist/cdn/code-block/snice-code-block.min.js +2 -2
- package/dist/cdn/code-block/snice-code-block.min.js.map +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-display/snice-color-display.min.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/comments/snice-comments.min.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/countdown/snice-countdown.min.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/cropper/snice-cropper.min.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/diff/snice-diff.min.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/divider/snice-divider.min.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/doc/snice-doc.min.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/draw/snice-draw.min.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/drawer/snice-drawer.min.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/flow/snice-flow.min.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gantt/snice-gantt.min.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/gauge/snice-gauge.min.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/image/snice-image.min.js +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/input/snice-input.min.js +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/kanban/snice-kanban.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/layout/snice-layout.min.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link/snice-link.min.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/list/snice-list.min.js +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/location/snice-location.min.js +1 -1
- package/dist/cdn/login/snice-login.js +1 -1
- package/dist/cdn/login/snice-login.min.js +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/map/snice-map.min.js +1 -1
- package/dist/cdn/markdown/snice-markdown.js +1 -1
- package/dist/cdn/markdown/snice-markdown.min.js +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/masonry/snice-masonry.min.js +1 -1
- package/dist/cdn/menu/snice-menu.js +1 -1
- package/dist/cdn/menu/snice-menu.min.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/modal/snice-modal.min.js +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/music-player/snice-music-player.min.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/nav/snice-nav.min.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/pagination/snice-pagination.min.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/paint/snice-paint.min.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
- package/dist/cdn/progress/snice-progress.js +1 -1
- package/dist/cdn/progress/snice-progress.min.js +1 -1
- package/dist/cdn/qr-code/README.md +2 -2
- package/dist/cdn/qr-code/snice-qr-code.js +149 -20
- package/dist/cdn/qr-code/snice-qr-code.js.map +1 -1
- package/dist/cdn/qr-code/snice-qr-code.min.js +3 -3
- package/dist/cdn/qr-code/snice-qr-code.min.js.map +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/radio/snice-radio.min.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/rating/snice-rating.min.js +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/recipe/snice-recipe.min.js +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.js +4 -4
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +3 -3
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +4 -4
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +3 -3
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/sankey/snice-sankey.min.js +1 -1
- package/dist/cdn/select/snice-select.js +1 -1
- package/dist/cdn/select/snice-select.min.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
- package/dist/cdn/slider/snice-slider.js +2 -2
- package/dist/cdn/slider/snice-slider.js.map +1 -1
- package/dist/cdn/slider/snice-slider.min.js +5 -5
- package/dist/cdn/slider/snice-slider.min.js.map +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sortable/snice-sortable.min.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/spinner/snice-spinner.min.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
- package/dist/cdn/spreadsheet/snice-spreadsheet.js +1 -1
- package/dist/cdn/spreadsheet/snice-spreadsheet.min.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/stepper/snice-stepper.min.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/switch/snice-switch.min.js +1 -1
- package/dist/cdn/table/snice-table.js +1 -1
- package/dist/cdn/table/snice-table.min.js +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tabs/snice-tabs.min.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/terminal/snice-terminal.min.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/textarea/snice-textarea.min.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timeline/snice-timeline.min.js +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/timer/snice-timer.min.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/toast/snice-toast.min.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/tree/snice-tree.min.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/treemap/snice-treemap.min.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/video-player/snice-video-player.min.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/weather/snice-weather.min.js +1 -1
- package/dist/components/code-block/snice-code-block.js +1 -1
- package/dist/components/code-block/snice-code-block.js.map +1 -1
- package/dist/components/qr-code/qrcode.d.ts +1 -0
- package/dist/components/qr-code/qrcode.js +16 -8
- package/dist/components/qr-code/qrcode.js.map +1 -1
- package/dist/components/qr-code/snice-qr-code.d.ts +5 -2
- package/dist/components/qr-code/snice-qr-code.js +132 -11
- package/dist/components/qr-code/snice-qr-code.js.map +1 -1
- package/dist/components/qr-code/snice-qr-code.types.d.ts +3 -2
- package/dist/components/slider/snice-slider.js +1 -1
- package/dist/components/slider/snice-slider.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.esm.js +2 -2
- package/dist/index.iife.js +2 -2
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/request-options.d.ts +1 -1
- package/docs/ai/api.md +1 -1
- package/docs/ai/components/code-block.md +1 -1
- package/docs/ai/decorators.md +2 -2
- package/docs/ai/patterns.md +17 -6
- package/docs/code-block.md +1 -3
- package/docs/controllers.md +98 -391
- package/docs/elements.md +131 -117
- package/docs/events.md +74 -83
- package/docs/fetcher.md +64 -76
- package/docs/observe.md +13 -33
- package/docs/placards.md +6 -16
- package/docs/request-response.md +171 -693
- package/docs/routing.md +67 -136
- package/package.json +1 -1
- package/docs/migration-v2-to-v3.md +0 -569
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v4.
|
|
2
|
+
* snice v4.13.0
|
|
3
3
|
* Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
|
|
4
4
|
* (c) 2024
|
|
5
5
|
* Released under the MIT License.
|
|
@@ -800,9 +800,11 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
800
800
|
draw(qrCode) {
|
|
801
801
|
const opts = this.options;
|
|
802
802
|
const nCount = qrCode.getModuleCount();
|
|
803
|
+
const margin = opts.margin || 0;
|
|
804
|
+
const totalSize = nCount + margin * 2;
|
|
803
805
|
this.clear();
|
|
804
806
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
|
805
|
-
svg.setAttribute('viewBox', `0 0 ${
|
|
807
|
+
svg.setAttribute('viewBox', `0 0 ${totalSize} ${totalSize}`);
|
|
806
808
|
svg.setAttribute('width', '100%');
|
|
807
809
|
svg.setAttribute('height', '100%');
|
|
808
810
|
svg.setAttribute('fill', opts.colorLight);
|
|
@@ -823,8 +825,8 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
823
825
|
for (let col = 0; col < nCount; col++) {
|
|
824
826
|
if (qrCode.isDark(row, col)) {
|
|
825
827
|
const use = this.createSVGElement('use', {
|
|
826
|
-
x: String(col),
|
|
827
|
-
y: String(row)
|
|
828
|
+
x: String(margin + col),
|
|
829
|
+
y: String(margin + row)
|
|
828
830
|
});
|
|
829
831
|
use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#template');
|
|
830
832
|
svg.appendChild(use);
|
|
@@ -870,17 +872,22 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
870
872
|
return;
|
|
871
873
|
const opts = this.options;
|
|
872
874
|
const ctx = this.context;
|
|
875
|
+
const margin = opts.margin || 0;
|
|
873
876
|
const nCount = qrCode.getModuleCount();
|
|
874
|
-
const
|
|
875
|
-
const
|
|
877
|
+
const drawSize = Math.min(opts.width, opts.height) - margin * 2;
|
|
878
|
+
const nWidth = drawSize / nCount;
|
|
879
|
+
const nHeight = drawSize / nCount;
|
|
876
880
|
const nRoundedWidth = Math.round(nWidth);
|
|
877
881
|
const nRoundedHeight = Math.round(nHeight);
|
|
878
882
|
this.clear();
|
|
883
|
+
// Fill background including quiet zone
|
|
884
|
+
ctx.fillStyle = opts.colorLight;
|
|
885
|
+
ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
|
|
879
886
|
for (let row = 0; row < nCount; row++) {
|
|
880
887
|
for (let col = 0; col < nCount; col++) {
|
|
881
888
|
const bIsDark = qrCode.isDark(row, col);
|
|
882
|
-
const nLeft = col * nWidth;
|
|
883
|
-
const nTop = row * nHeight;
|
|
889
|
+
const nLeft = margin + col * nWidth;
|
|
890
|
+
const nTop = margin + row * nHeight;
|
|
884
891
|
const color = bIsDark ? opts.colorDark : opts.colorLight;
|
|
885
892
|
ctx.fillStyle = color;
|
|
886
893
|
if (opts.dotStyle === 'dots') {
|
|
@@ -944,7 +951,8 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
944
951
|
colorLight: '#ffffff',
|
|
945
952
|
correctLevel: 'H',
|
|
946
953
|
useSVG: false,
|
|
947
|
-
dotStyle: 'square'
|
|
954
|
+
dotStyle: 'square',
|
|
955
|
+
margin: 4
|
|
948
956
|
};
|
|
949
957
|
let opts = vOption;
|
|
950
958
|
if (typeof opts === 'string') {
|
|
@@ -1153,7 +1161,8 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
1153
1161
|
colorLight: this.bgColor,
|
|
1154
1162
|
correctLevel: correctLevel,
|
|
1155
1163
|
useSVG: this.renderMode === 'svg',
|
|
1156
|
-
dotStyle: this.dotStyle
|
|
1164
|
+
dotStyle: this.dotStyle,
|
|
1165
|
+
margin: this.margin
|
|
1157
1166
|
});
|
|
1158
1167
|
// Apply overlays after QR code is rendered
|
|
1159
1168
|
requestAnimationFrame(() => {
|
|
@@ -1161,7 +1170,11 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
1161
1170
|
});
|
|
1162
1171
|
}
|
|
1163
1172
|
applyOverlays() {
|
|
1164
|
-
|
|
1173
|
+
const svg = this.container?.querySelector('svg');
|
|
1174
|
+
if (svg) {
|
|
1175
|
+
this.applySvgOverlays(svg);
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1165
1178
|
const canvas = this.container?.querySelector('canvas');
|
|
1166
1179
|
if (!canvas)
|
|
1167
1180
|
return;
|
|
@@ -1170,11 +1183,24 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
1170
1183
|
ctx = canvas.getContext('2d');
|
|
1171
1184
|
}
|
|
1172
1185
|
catch (e) {
|
|
1173
|
-
// Canvas not supported in test environment
|
|
1174
1186
|
return;
|
|
1175
1187
|
}
|
|
1176
1188
|
if (!ctx)
|
|
1177
1189
|
return;
|
|
1190
|
+
// Apply quiet zone margin by re-drawing canvas content inset
|
|
1191
|
+
const m = this.margin;
|
|
1192
|
+
if (m > 0) {
|
|
1193
|
+
const s = this.size;
|
|
1194
|
+
const inner = s - m * 2;
|
|
1195
|
+
const imgData = ctx.getImageData(0, 0, s, s);
|
|
1196
|
+
const off = document.createElement('canvas');
|
|
1197
|
+
off.width = s;
|
|
1198
|
+
off.height = s;
|
|
1199
|
+
off.getContext('2d').putImageData(imgData, 0, 0);
|
|
1200
|
+
ctx.fillStyle = this.bgColor;
|
|
1201
|
+
ctx.fillRect(0, 0, s, s);
|
|
1202
|
+
ctx.drawImage(off, 0, 0, s, s, m, m, inner, inner);
|
|
1203
|
+
}
|
|
1178
1204
|
// Center image overlay
|
|
1179
1205
|
if (this.includeImage && this.imageUrl) {
|
|
1180
1206
|
const img = new Image();
|
|
@@ -1183,9 +1209,7 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
1183
1209
|
const imgSize = this.imageSize;
|
|
1184
1210
|
const imgX = (this.size - imgSize) / 2;
|
|
1185
1211
|
const imgY = (this.size - imgSize) / 2;
|
|
1186
|
-
// Draw image directly without background
|
|
1187
1212
|
ctx.drawImage(img, imgX, imgY, imgSize, imgSize);
|
|
1188
|
-
// Apply center text after image if both are present
|
|
1189
1213
|
if (this.centerText) {
|
|
1190
1214
|
this.drawCenterText(ctx);
|
|
1191
1215
|
}
|
|
@@ -1193,39 +1217,144 @@ var SniceQrCode = (function (exports, snice) {
|
|
|
1193
1217
|
img.src = this.imageUrl;
|
|
1194
1218
|
}
|
|
1195
1219
|
else if (this.centerText) {
|
|
1196
|
-
// Center text overlay only
|
|
1197
1220
|
this.drawCenterText(ctx);
|
|
1198
1221
|
}
|
|
1199
1222
|
}
|
|
1223
|
+
applySvgOverlays(svg) {
|
|
1224
|
+
// Get viewBox dimensions to position overlays in SVG coordinate space
|
|
1225
|
+
const vb = svg.getAttribute('viewBox')?.split(' ').map(Number) || [];
|
|
1226
|
+
const vbSize = vb[2] || 100;
|
|
1227
|
+
const center = vbSize / 2;
|
|
1228
|
+
// Scale factor: SVG viewBox units per pixel
|
|
1229
|
+
const scale = vbSize / this.size;
|
|
1230
|
+
// Center image overlay
|
|
1231
|
+
if (this.includeImage && this.imageUrl) {
|
|
1232
|
+
const imgSize = this.imageSize * scale;
|
|
1233
|
+
const imgX = center - imgSize / 2;
|
|
1234
|
+
const imgY = center - imgSize / 2;
|
|
1235
|
+
// Convert image to data URL for embedding in SVG
|
|
1236
|
+
const img = new Image();
|
|
1237
|
+
img.crossOrigin = 'anonymous';
|
|
1238
|
+
img.onload = () => {
|
|
1239
|
+
// Draw to temp canvas to get data URL
|
|
1240
|
+
const off = document.createElement('canvas');
|
|
1241
|
+
off.width = img.naturalWidth;
|
|
1242
|
+
off.height = img.naturalHeight;
|
|
1243
|
+
off.getContext('2d').drawImage(img, 0, 0);
|
|
1244
|
+
const dataUrl = off.toDataURL('image/png');
|
|
1245
|
+
const svgImg = document.createElementNS('http://www.w3.org/2000/svg', 'image');
|
|
1246
|
+
svgImg.setAttribute('x', String(imgX));
|
|
1247
|
+
svgImg.setAttribute('y', String(imgY));
|
|
1248
|
+
svgImg.setAttribute('width', String(imgSize));
|
|
1249
|
+
svgImg.setAttribute('height', String(imgSize));
|
|
1250
|
+
svgImg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', dataUrl);
|
|
1251
|
+
svg.appendChild(svgImg);
|
|
1252
|
+
if (this.centerText) {
|
|
1253
|
+
this.drawSvgCenterText(svg, center, scale);
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1256
|
+
img.src = this.imageUrl;
|
|
1257
|
+
}
|
|
1258
|
+
else if (this.centerText) {
|
|
1259
|
+
this.drawSvgCenterText(svg, center, scale);
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
drawSvgCenterText(svg, center, scale) {
|
|
1263
|
+
const fontSize = this.centerTextSize * scale;
|
|
1264
|
+
const strokeWidth = 6 * scale;
|
|
1265
|
+
// Outline text
|
|
1266
|
+
const outline = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
1267
|
+
outline.setAttribute('x', String(center));
|
|
1268
|
+
outline.setAttribute('y', String(center));
|
|
1269
|
+
outline.setAttribute('text-anchor', 'middle');
|
|
1270
|
+
outline.setAttribute('dominant-baseline', 'central');
|
|
1271
|
+
outline.setAttribute('font-size', String(fontSize));
|
|
1272
|
+
outline.setAttribute('font-weight', 'bold');
|
|
1273
|
+
outline.setAttribute('font-family', 'sans-serif');
|
|
1274
|
+
outline.setAttribute('stroke', this.textOutlineColor);
|
|
1275
|
+
outline.setAttribute('stroke-width', String(strokeWidth));
|
|
1276
|
+
outline.setAttribute('stroke-linejoin', 'round');
|
|
1277
|
+
outline.setAttribute('fill', this.textOutlineColor);
|
|
1278
|
+
outline.textContent = this.centerText;
|
|
1279
|
+
svg.appendChild(outline);
|
|
1280
|
+
// Fill text
|
|
1281
|
+
const fill = document.createElementNS('http://www.w3.org/2000/svg', 'text');
|
|
1282
|
+
fill.setAttribute('x', String(center));
|
|
1283
|
+
fill.setAttribute('y', String(center));
|
|
1284
|
+
fill.setAttribute('text-anchor', 'middle');
|
|
1285
|
+
fill.setAttribute('dominant-baseline', 'central');
|
|
1286
|
+
fill.setAttribute('font-size', String(fontSize));
|
|
1287
|
+
fill.setAttribute('font-weight', 'bold');
|
|
1288
|
+
fill.setAttribute('font-family', 'sans-serif');
|
|
1289
|
+
fill.setAttribute('fill', this.textFillColor);
|
|
1290
|
+
fill.textContent = this.centerText;
|
|
1291
|
+
svg.appendChild(fill);
|
|
1292
|
+
}
|
|
1200
1293
|
drawCenterText(ctx) {
|
|
1201
1294
|
ctx.font = `bold ${this.centerTextSize}px sans-serif`;
|
|
1202
1295
|
ctx.textAlign = 'center';
|
|
1203
1296
|
ctx.textBaseline = 'middle';
|
|
1204
1297
|
const x = this.size / 2;
|
|
1205
1298
|
const y = this.size / 2;
|
|
1206
|
-
// Draw text outline (stroke)
|
|
1207
1299
|
ctx.strokeStyle = this.textOutlineColor;
|
|
1208
1300
|
ctx.lineWidth = 6;
|
|
1209
1301
|
ctx.lineJoin = 'round';
|
|
1210
1302
|
ctx.miterLimit = 2;
|
|
1211
1303
|
ctx.strokeText(this.centerText, x, y);
|
|
1212
|
-
// Draw text fill
|
|
1213
1304
|
ctx.fillStyle = this.textFillColor;
|
|
1214
1305
|
ctx.fillText(this.centerText, x, y);
|
|
1215
1306
|
}
|
|
1307
|
+
toSVGString() {
|
|
1308
|
+
const svg = this.container?.querySelector('svg');
|
|
1309
|
+
if (!svg)
|
|
1310
|
+
return '';
|
|
1311
|
+
return new XMLSerializer().serializeToString(svg);
|
|
1312
|
+
}
|
|
1216
1313
|
async toDataURL(type = 'image/png', quality = 0.92) {
|
|
1314
|
+
// SVG export
|
|
1315
|
+
if (type === 'image/svg+xml') {
|
|
1316
|
+
const svgStr = this.toSVGString();
|
|
1317
|
+
if (!svgStr)
|
|
1318
|
+
return '';
|
|
1319
|
+
return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgStr);
|
|
1320
|
+
}
|
|
1321
|
+
// Canvas export (rasterize SVG if in SVG mode)
|
|
1217
1322
|
const canvas = this.container?.querySelector('canvas');
|
|
1218
|
-
if (
|
|
1323
|
+
if (canvas)
|
|
1324
|
+
return canvas.toDataURL(type, quality);
|
|
1325
|
+
// SVG mode but raster export requested — rasterize to canvas
|
|
1326
|
+
const svg = this.container?.querySelector('svg');
|
|
1327
|
+
if (!svg)
|
|
1219
1328
|
return '';
|
|
1220
|
-
|
|
1329
|
+
const svgStr = new XMLSerializer().serializeToString(svg);
|
|
1330
|
+
const blob = new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
|
|
1331
|
+
const url = URL.createObjectURL(blob);
|
|
1332
|
+
const img = new Image();
|
|
1333
|
+
return new Promise((resolve) => {
|
|
1334
|
+
img.onload = () => {
|
|
1335
|
+
const off = document.createElement('canvas');
|
|
1336
|
+
off.width = this.size;
|
|
1337
|
+
off.height = this.size;
|
|
1338
|
+
off.getContext('2d').drawImage(img, 0, 0, this.size, this.size);
|
|
1339
|
+
URL.revokeObjectURL(url);
|
|
1340
|
+
resolve(off.toDataURL(type, quality));
|
|
1341
|
+
};
|
|
1342
|
+
img.onerror = () => { URL.revokeObjectURL(url); resolve(''); };
|
|
1343
|
+
img.src = url;
|
|
1344
|
+
});
|
|
1221
1345
|
}
|
|
1222
1346
|
async toBlob(type = 'image/png', quality = 0.92) {
|
|
1347
|
+
if (type === 'image/svg+xml') {
|
|
1348
|
+
const svgStr = this.toSVGString();
|
|
1349
|
+
return new Blob([svgStr], { type: 'image/svg+xml;charset=utf-8' });
|
|
1350
|
+
}
|
|
1223
1351
|
const dataURL = await this.toDataURL(type, quality);
|
|
1224
1352
|
const response = await fetch(dataURL);
|
|
1225
1353
|
return response.blob();
|
|
1226
1354
|
}
|
|
1227
1355
|
async download(filename = 'qr-code.png') {
|
|
1228
|
-
const
|
|
1356
|
+
const isSvg = filename.endsWith('.svg');
|
|
1357
|
+
const dataURL = await this.toDataURL(isSvg ? 'image/svg+xml' : 'image/png');
|
|
1229
1358
|
const a = document.createElement('a');
|
|
1230
1359
|
a.href = dataURL;
|
|
1231
1360
|
a.download = filename;
|