dpzvc3-ui 3.0.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/LICENSE +20 -0
- package/README.md +175 -0
- package/build-style.js +58 -0
- package/dist/dpzvc3.esm.js +17676 -0
- package/dist/dpzvc3.esm.js.map +1 -0
- package/dist/dpzvc3.esm.min.js +2 -0
- package/dist/dpzvc3.esm.min.js.map +1 -0
- package/dist/dpzvc3.js +15200 -0
- package/dist/dpzvc3.js.map +1 -0
- package/dist/dpzvc3.min.js +2 -0
- package/dist/dpzvc3.min.js.map +1 -0
- package/dist/styles/base/font.css +1 -0
- package/dist/styles/base/reset.css +1 -0
- package/dist/styles/base/variable.css +0 -0
- package/dist/styles/components/actionSheet.css +1 -0
- package/dist/styles/components/badge.css +1 -0
- package/dist/styles/components/button.css +1 -0
- package/dist/styles/components/card.css +1 -0
- package/dist/styles/components/cell-swipe.css +1 -0
- package/dist/styles/components/cell.css +1 -0
- package/dist/styles/components/checkBox.css +1 -0
- package/dist/styles/components/editor.css +1 -0
- package/dist/styles/components/header.css +1 -0
- package/dist/styles/components/indicator.css +1 -0
- package/dist/styles/components/loadmore.css +1 -0
- package/dist/styles/components/message.css +1 -0
- package/dist/styles/components/modal.css +1 -0
- package/dist/styles/components/number.css +1 -0
- package/dist/styles/components/picker.css +1 -0
- package/dist/styles/components/popup.css +1 -0
- package/dist/styles/components/progress.css +1 -0
- package/dist/styles/components/prompt.css +1 -0
- package/dist/styles/components/radioBox.css +1 -0
- package/dist/styles/components/slide-Bar.css +1 -0
- package/dist/styles/components/spinner.css +1 -0
- package/dist/styles/components/swipe.css +1 -0
- package/dist/styles/components/switchBar.css +1 -0
- package/dist/styles/components/tab.css +1 -0
- package/dist/styles/components/text.css +1 -0
- package/dist/styles/components/toTop.css +1 -0
- package/dist/styles/components/upload.css +1 -0
- package/dist/styles/dpzvc3.css +1 -0
- package/dist/styles/utils/1px.css +1 -0
- package/dist/styles/utils/animation.css +1 -0
- package/dist/styles/utils/nowrap.css +1 -0
- package/dist-prod/91.9d79b442ec3131707419.js +3 -0
- package/dist-prod/91.9d79b442ec3131707419.js.LICENSE.txt +25 -0
- package/dist-prod/91.9d79b442ec3131707419.js.map +1 -0
- package/dist-prod/actionsheet.e2f7c32d0120f5147a4f.chunk.js +2 -0
- package/dist-prod/actionsheet.e2f7c32d0120f5147a4f.chunk.js.map +1 -0
- package/dist-prod/badge.6038c4ccc54ffb56a645.chunk.js +2 -0
- package/dist-prod/badge.6038c4ccc54ffb56a645.chunk.js.map +1 -0
- package/dist-prod/button.28b491339fbba29c3f16.chunk.js +2 -0
- package/dist-prod/button.28b491339fbba29c3f16.chunk.js.map +1 -0
- package/dist-prod/card.3ad847f07bebc1391125.chunk.js +2 -0
- package/dist-prod/card.3ad847f07bebc1391125.chunk.js.map +1 -0
- package/dist-prod/cell.8920796a9ebd2d84bbd3.chunk.js +2 -0
- package/dist-prod/cell.8920796a9ebd2d84bbd3.chunk.js.map +1 -0
- package/dist-prod/cellswipe.53b0178e4638c201dcf1.chunk.js +2 -0
- package/dist-prod/cellswipe.53b0178e4638c201dcf1.chunk.js.map +1 -0
- package/dist-prod/checkbox.87403976981ee0f64f4a.chunk.js +2 -0
- package/dist-prod/checkbox.87403976981ee0f64f4a.chunk.js.map +1 -0
- package/dist-prod/guide.5195c74796a7a0e37f7b.chunk.js +2 -0
- package/dist-prod/guide.5195c74796a7a0e37f7b.chunk.js.map +1 -0
- package/dist-prod/header.e3cecc6d60f801c1c105.chunk.js +2 -0
- package/dist-prod/header.e3cecc6d60f801c1c105.chunk.js.map +1 -0
- package/dist-prod/index.html +19 -0
- package/dist-prod/indicator.6b0c7a91ca254c3586e8.chunk.js +2 -0
- package/dist-prod/indicator.6b0c7a91ca254c3586e8.chunk.js.map +1 -0
- package/dist-prod/loadmore.ba86c35311fc68ee215b.chunk.js +2 -0
- package/dist-prod/loadmore.ba86c35311fc68ee215b.chunk.js.map +1 -0
- package/dist-prod/main.2e9aaa9095e329ea2d7b.js +2 -0
- package/dist-prod/main.2e9aaa9095e329ea2d7b.js.map +1 -0
- package/dist-prod/message.e57fa263a214006f7191.chunk.js +2 -0
- package/dist-prod/message.e57fa263a214006f7191.chunk.js.map +1 -0
- package/dist-prod/modal.1172c8ba7d90503fc8e8.chunk.js +2 -0
- package/dist-prod/modal.1172c8ba7d90503fc8e8.chunk.js.map +1 -0
- package/dist-prod/picker.4ff114161c5c3f8df57a.chunk.js +2 -0
- package/dist-prod/picker.4ff114161c5c3f8df57a.chunk.js.map +1 -0
- package/dist-prod/popup.8f92c027932e4d47fa59.chunk.js +2 -0
- package/dist-prod/popup.8f92c027932e4d47fa59.chunk.js.map +1 -0
- package/dist-prod/progress.1e0d785044aecadc5615.chunk.js +2 -0
- package/dist-prod/progress.1e0d785044aecadc5615.chunk.js.map +1 -0
- package/dist-prod/prompt.c2b442c3dd0e6d8319bc.chunk.js +2 -0
- package/dist-prod/prompt.c2b442c3dd0e6d8319bc.chunk.js.map +1 -0
- package/dist-prod/radiobox.479703c69b75d473e85d.chunk.js +2 -0
- package/dist-prod/radiobox.479703c69b75d473e85d.chunk.js.map +1 -0
- package/dist-prod/rater.939e0e7e770728f684c3.chunk.js +2 -0
- package/dist-prod/rater.939e0e7e770728f684c3.chunk.js.map +1 -0
- package/dist-prod/slidebar.3d3f48a631f03a2210c9.chunk.js +2 -0
- package/dist-prod/slidebar.3d3f48a631f03a2210c9.chunk.js.map +1 -0
- package/dist-prod/spinner.f20e3bd8cec27d26afe0.chunk.js +2 -0
- package/dist-prod/spinner.f20e3bd8cec27d26afe0.chunk.js.map +1 -0
- package/dist-prod/swipe.2e5b0acc3bbb2bf49dd5.chunk.js +2 -0
- package/dist-prod/swipe.2e5b0acc3bbb2bf49dd5.chunk.js.map +1 -0
- package/dist-prod/switchbar.56d03d96c275ff4c65a1.chunk.js +2 -0
- package/dist-prod/switchbar.56d03d96c275ff4c65a1.chunk.js.map +1 -0
- package/dist-prod/tab.4c391211c41b7d12b585.chunk.js +2 -0
- package/dist-prod/tab.4c391211c41b7d12b585.chunk.js.map +1 -0
- package/dist-prod/text.ee2804ba87e6a460aa7d.chunk.js +2 -0
- package/dist-prod/text.ee2804ba87e6a460aa7d.chunk.js.map +1 -0
- package/dist-prod/totop.c6f9dce152bb6abe5cb2.chunk.js +2 -0
- package/dist-prod/totop.c6f9dce152bb6abe5cb2.chunk.js.map +1 -0
- package/dist-prod/upload.ec7a954970889869d93e.chunk.js +2 -0
- package/dist-prod/upload.ec7a954970889869d93e.chunk.js.map +1 -0
- package/images/IMG_2614 2 2.JPG +0 -0
- package/images/IMG_2614.JPG +0 -0
- package/images/IMG_2615 2.JPG +0 -0
- package/images/IMG_2615.JPG +0 -0
- package/package.json +113 -0
- package/postcss.config.js +5 -0
- package/src/components/Indicator/Indicator.vue +82 -0
- package/src/components/Indicator/index.js +86 -0
- package/src/components/Text/Number.vue +167 -0
- package/src/components/Text/index.js +7 -0
- package/src/components/Text/textBar.vue +122 -0
- package/src/components/action-sheet/actionSheet.vue +93 -0
- package/src/components/action-sheet/index.js +5 -0
- package/src/components/app.vue +61 -0
- package/src/components/badge/badge.vue +80 -0
- package/src/components/badge/index.js +5 -0
- package/src/components/button/button.vue +111 -0
- package/src/components/button/index.js +5 -0
- package/src/components/card/card.vue +49 -0
- package/src/components/card/index.js +5 -0
- package/src/components/cell/cell.vue +93 -0
- package/src/components/cell/index.js +5 -0
- package/src/components/cell-swipe/cell-swipe.vue +169 -0
- package/src/components/cell-swipe/index.js +5 -0
- package/src/components/checkBox/checkbox-group.vue +74 -0
- package/src/components/checkBox/checkbox.vue +117 -0
- package/src/components/checkBox/index.js +8 -0
- package/src/components/header/header.vue +130 -0
- package/src/components/header/index.js +5 -0
- package/src/components/loadMore/index.js +5 -0
- package/src/components/loadMore/loadmore.vue +258 -0
- package/src/components/message/confirm.js +60 -0
- package/src/components/message/index.js +111 -0
- package/src/components/message/message.vue +137 -0
- package/src/components/message/messageGroup.vue +82 -0
- package/src/components/modal/confirm.js +122 -0
- package/src/components/modal/index.js +52 -0
- package/src/components/modal/modal.vue +138 -0
- package/src/components/picker/area-picker/area-picker.vue +230 -0
- package/src/components/picker/area-picker/props.js +17 -0
- package/src/components/picker/date-picker/date-picker.vue +191 -0
- package/src/components/picker/date-picker/props.js +24 -0
- package/src/components/picker/index.js +5 -0
- package/src/components/picker/normal-picker/normal-picker.vue +120 -0
- package/src/components/picker/normal-picker/props.js +20 -0
- package/src/components/picker/picker-slot.vue +217 -0
- package/src/components/picker/picker.vue +111 -0
- package/src/components/popup/index.js +5 -0
- package/src/components/popup/popup.vue +91 -0
- package/src/components/progress/index.js +5 -0
- package/src/components/progress/progress.vue +86 -0
- package/src/components/prompt/confirm.js +91 -0
- package/src/components/prompt/index.js +53 -0
- package/src/components/prompt/prompt.vue +125 -0
- package/src/components/radioBox/index.js +8 -0
- package/src/components/radioBox/radiobox-group.vue +66 -0
- package/src/components/radioBox/radiobox.vue +88 -0
- package/src/components/rater/index.js +5 -0
- package/src/components/rater/rater.vue +118 -0
- package/src/components/slideBar/index.js +6 -0
- package/src/components/slideBar/slideBar.vue +207 -0
- package/src/components/spinner/behavior/blade.vue +42 -0
- package/src/components/spinner/behavior/double-bounce.vue +38 -0
- package/src/components/spinner/behavior/fading-circle.vue +55 -0
- package/src/components/spinner/behavior/snake.vue +41 -0
- package/src/components/spinner/behavior/triple-bounce.vue +52 -0
- package/src/components/spinner/index.js +5 -0
- package/src/components/spinner/props.js +28 -0
- package/src/components/spinner/spinner.vue +78 -0
- package/src/components/swipe/index.js +5 -0
- package/src/components/swipe/swipe.vue +281 -0
- package/src/components/switchbar/index.js +5 -0
- package/src/components/switchbar/switchbar.vue +79 -0
- package/src/components/tab/index.js +6 -0
- package/src/components/tab/tab.vue +89 -0
- package/src/components/toTop/index.js +5 -0
- package/src/components/toTop/topTop.vue +78 -0
- package/src/components/upload/index.js +5 -0
- package/src/components/upload/upload.vue +166 -0
- package/src/config/config.js +16 -0
- package/src/directives/clickoutside.js +42 -0
- package/src/directives/tranferDom.js +66 -0
- package/src/index.js +149 -0
- package/src/lib/MegaPixImage.js +163 -0
- package/src/lib/MegaPixImageOld.js +153 -0
- package/src/lib/exif-js.js +235 -0
- package/src/lib/exif.js +789 -0
- package/src/main.js +31 -0
- package/src/mixin/emitter.js +72 -0
- package/src/mixin/input.js +41 -0
- package/src/router.js +36 -0
- package/src/styles/base/font.less +99 -0
- package/src/styles/base/reset.less +135 -0
- package/src/styles/base/variable.less +108 -0
- package/src/styles/components/actionSheet.less +43 -0
- package/src/styles/components/badge.less +81 -0
- package/src/styles/components/button.less +124 -0
- package/src/styles/components/card.less +31 -0
- package/src/styles/components/cell-swipe.less +20 -0
- package/src/styles/components/cell.less +75 -0
- package/src/styles/components/checkBox.less +113 -0
- package/src/styles/components/editor.less +3 -0
- package/src/styles/components/header.less +72 -0
- package/src/styles/components/indicator.less +39 -0
- package/src/styles/components/loadmore.less +48 -0
- package/src/styles/components/message.less +57 -0
- package/src/styles/components/modal.less +84 -0
- package/src/styles/components/number.less +60 -0
- package/src/styles/components/picker.less +152 -0
- package/src/styles/components/popup.less +46 -0
- package/src/styles/components/progress.less +52 -0
- package/src/styles/components/prompt.less +37 -0
- package/src/styles/components/radioBox.less +138 -0
- package/src/styles/components/slide-Bar.less +149 -0
- package/src/styles/components/spinner.less +329 -0
- package/src/styles/components/swipe.less +125 -0
- package/src/styles/components/switchBar.less +88 -0
- package/src/styles/components/tab.less +71 -0
- package/src/styles/components/text.less +82 -0
- package/src/styles/components/toTop.less +28 -0
- package/src/styles/components/upload.less +23 -0
- package/src/styles/index.less +38 -0
- package/src/styles/utils/1px.less +206 -0
- package/src/styles/utils/animation.less +165 -0
- package/src/styles/utils/nowrap.less +19 -0
- package/src/template/index.ejs +40 -0
- package/src/utils/util.js +202 -0
- package/src/vconsole-resources.min.js +6 -0
- package/src/vconsole-sources.min.js +6 -0
- package/src/vconsole.min.js +7 -0
- package/src/views/ActionSheet.vue +46 -0
- package/src/views/Badge.vue +51 -0
- package/src/views/Button.vue +69 -0
- package/src/views/Card.vue +88 -0
- package/src/views/Cell.vue +30 -0
- package/src/views/CellSwipe.vue +68 -0
- package/src/views/CheckBox.vue +77 -0
- package/src/views/Header.vue +70 -0
- package/src/views/Indicator.vue +82 -0
- package/src/views/LoadMore.vue +73 -0
- package/src/views/Message.vue +61 -0
- package/src/views/Modal.vue +69 -0
- package/src/views/Picker.vue +140 -0
- package/src/views/Popup.vue +97 -0
- package/src/views/Progress.vue +47 -0
- package/src/views/Prompt.vue +43 -0
- package/src/views/RadioBox.vue +68 -0
- package/src/views/Rater.vue +49 -0
- package/src/views/SlideBar.vue +55 -0
- package/src/views/Spinner.vue +15 -0
- package/src/views/Swipe.vue +59 -0
- package/src/views/SwitchBar.vue +47 -0
- package/src/views/Tab.vue +53 -0
- package/src/views/Text.vue +93 -0
- package/src/views/ToTop.vue +17 -0
- package/src/views/Upload.vue +61 -0
- package/src/views/guide.vue +164 -0
- package/src/views/index.vue +554 -0
- package/webpack.base.config.js +65 -0
- package/webpack.dev.config.js +42 -0
- package/webpack.dist.dev.config.js +75 -0
- package/webpack.dist.prod.config.js +89 -0
- package/webpack.prod.config.js +51 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// MegaPixImage.js
|
|
2
|
+
// 将原先的 UMD/CommonJS 改为 ESM export default
|
|
3
|
+
|
|
4
|
+
// -------------------------
|
|
5
|
+
// Helper functions
|
|
6
|
+
// -------------------------
|
|
7
|
+
function detectSubsampling (img) {
|
|
8
|
+
const iw = img.naturalWidth; const ih = img.naturalHeight
|
|
9
|
+
if (iw * ih > 1024 * 1024) {
|
|
10
|
+
const canvas = document.createElement('canvas')
|
|
11
|
+
canvas.width = canvas.height = 1
|
|
12
|
+
const ctx = canvas.getContext('2d')
|
|
13
|
+
ctx.drawImage(img, -iw + 1, 0)
|
|
14
|
+
return ctx.getImageData(0, 0, 1, 1).data[3] === 0
|
|
15
|
+
}
|
|
16
|
+
return false
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function detectVerticalSquash (img, iw, ih) {
|
|
20
|
+
const canvas = document.createElement('canvas')
|
|
21
|
+
canvas.width = 1
|
|
22
|
+
canvas.height = ih
|
|
23
|
+
const ctx = canvas.getContext('2d')
|
|
24
|
+
ctx.drawImage(img, 0, 0)
|
|
25
|
+
const data = ctx.getImageData(0, 0, 1, ih).data
|
|
26
|
+
let sy = 0; let ey = ih; let py = ih
|
|
27
|
+
while (py > sy) {
|
|
28
|
+
const alpha = data[(py - 1) * 4 + 3]
|
|
29
|
+
if (alpha === 0) ey = py
|
|
30
|
+
else sy = py
|
|
31
|
+
py = (ey + sy) >> 1
|
|
32
|
+
}
|
|
33
|
+
const ratio = py / ih
|
|
34
|
+
return ratio === 0 ? 1 : ratio
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function renderImageToDataURL (img, options, doSquash) {
|
|
38
|
+
const canvas = document.createElement('canvas')
|
|
39
|
+
renderImageToCanvas(img, canvas, options, doSquash)
|
|
40
|
+
return canvas.toDataURL('image/jpeg', options.quality || 0.8)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function renderImageToCanvas (img, canvas, options, doSquash) {
|
|
44
|
+
let iw = img.naturalWidth; let ih = img.naturalHeight
|
|
45
|
+
if (!(iw + ih)) return
|
|
46
|
+
|
|
47
|
+
const width = options.width; const height = options.height
|
|
48
|
+
const ctx = canvas.getContext('2d')
|
|
49
|
+
ctx.save()
|
|
50
|
+
transformCoordinate(canvas, ctx, width, height, options.orientation)
|
|
51
|
+
|
|
52
|
+
const subsampled = detectSubsampling(img)
|
|
53
|
+
if (subsampled) { iw /= 2; ih /= 2 }
|
|
54
|
+
|
|
55
|
+
const d = 1024
|
|
56
|
+
const tmpCanvas = document.createElement('canvas')
|
|
57
|
+
tmpCanvas.width = tmpCanvas.height = d
|
|
58
|
+
const tmpCtx = tmpCanvas.getContext('2d')
|
|
59
|
+
|
|
60
|
+
const vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1
|
|
61
|
+
const dw = Math.ceil(d * width / iw)
|
|
62
|
+
const dh = Math.ceil(d * height / ih / vertSquashRatio)
|
|
63
|
+
|
|
64
|
+
let sy = 0; let dy = 0
|
|
65
|
+
while (sy < ih) {
|
|
66
|
+
let sx = 0; let dx = 0
|
|
67
|
+
while (sx < iw) {
|
|
68
|
+
tmpCtx.clearRect(0, 0, d, d)
|
|
69
|
+
tmpCtx.drawImage(img, -sx, -sy)
|
|
70
|
+
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh)
|
|
71
|
+
sx += d
|
|
72
|
+
dx += dw
|
|
73
|
+
}
|
|
74
|
+
sy += d
|
|
75
|
+
dy += dh
|
|
76
|
+
}
|
|
77
|
+
ctx.restore()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function transformCoordinate (canvas, ctx, width, height, orientation) {
|
|
81
|
+
switch (orientation) {
|
|
82
|
+
case 5: case 6: case 7: case 8:
|
|
83
|
+
canvas.width = height
|
|
84
|
+
canvas.height = width
|
|
85
|
+
break
|
|
86
|
+
default:
|
|
87
|
+
canvas.width = width
|
|
88
|
+
canvas.height = height
|
|
89
|
+
}
|
|
90
|
+
switch (orientation) {
|
|
91
|
+
case 2: ctx.translate(width, 0); ctx.scale(-1, 1); break
|
|
92
|
+
case 3: ctx.translate(width, height); ctx.rotate(Math.PI); break
|
|
93
|
+
case 4: ctx.translate(0, height); ctx.scale(1, -1); break
|
|
94
|
+
case 5: ctx.rotate(0.5 * Math.PI); ctx.scale(1, -1); break
|
|
95
|
+
case 6: ctx.rotate(0.5 * Math.PI); ctx.translate(0, -height); break
|
|
96
|
+
case 7: ctx.rotate(0.5 * Math.PI); ctx.translate(width, -height); ctx.scale(-1, 1); break
|
|
97
|
+
case 8: ctx.rotate(-0.5 * Math.PI); ctx.translate(-width, 0); break
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const URL = window.URL && window.URL.createObjectURL
|
|
102
|
+
? window.URL
|
|
103
|
+
: window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null
|
|
104
|
+
|
|
105
|
+
// -------------------------
|
|
106
|
+
// MegaPixImage class
|
|
107
|
+
// -------------------------
|
|
108
|
+
class MegaPixImage {
|
|
109
|
+
constructor (srcImage) {
|
|
110
|
+
if (window.Blob && srcImage instanceof Blob) {
|
|
111
|
+
if (!URL) throw Error('No createObjectURL function found')
|
|
112
|
+
const img = new Image()
|
|
113
|
+
img.src = URL.createObjectURL(srcImage)
|
|
114
|
+
this.blob = srcImage
|
|
115
|
+
srcImage = img
|
|
116
|
+
}
|
|
117
|
+
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
|
|
118
|
+
this.imageLoadListeners = []
|
|
119
|
+
const _this = this
|
|
120
|
+
srcImage.onload = srcImage.onerror = function () {
|
|
121
|
+
const listeners = _this.imageLoadListeners
|
|
122
|
+
if (listeners) {
|
|
123
|
+
_this.imageLoadListeners = null
|
|
124
|
+
listeners.forEach(fn => fn())
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
this.srcImage = srcImage
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
render (target, options, callback) {
|
|
132
|
+
if (this.imageLoadListeners) {
|
|
133
|
+
this.imageLoadListeners.push(() => { this.render(target, options, callback) })
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
options = options || {}
|
|
137
|
+
const imgWidth = this.srcImage.naturalWidth; const imgHeight = this.srcImage.naturalHeight
|
|
138
|
+
let width = options.width; let height = options.height
|
|
139
|
+
const maxWidth = options.maxWidth; const maxHeight = options.maxHeight
|
|
140
|
+
const doSquash = !this.blob || this.blob.type === 'image/jpeg'
|
|
141
|
+
|
|
142
|
+
if (width && !height) height = (imgHeight * width / imgWidth) << 0
|
|
143
|
+
else if (height && !width) width = (imgWidth * height / imgHeight) << 0
|
|
144
|
+
else { width = imgWidth; height = imgHeight }
|
|
145
|
+
|
|
146
|
+
if (maxWidth && width > maxWidth) { width = maxWidth; height = (imgHeight * width / imgWidth) << 0 }
|
|
147
|
+
if (maxHeight && height > maxHeight) { height = maxHeight; width = (imgWidth * height / imgHeight) << 0 }
|
|
148
|
+
|
|
149
|
+
const opt = { width, height, ...options }
|
|
150
|
+
const tagName = target.tagName.toLowerCase()
|
|
151
|
+
if (tagName === 'img') target.src = renderImageToDataURL(this.srcImage, opt, doSquash)
|
|
152
|
+
else if (tagName === 'canvas') renderImageToCanvas(this.srcImage, target, opt, doSquash)
|
|
153
|
+
|
|
154
|
+
if (typeof this.onrender === 'function') this.onrender(target)
|
|
155
|
+
if (callback) callback()
|
|
156
|
+
if (this.blob) { this.blob = null; URL.revokeObjectURL(this.srcImage.src) }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// -------------------------
|
|
161
|
+
// ESM export default
|
|
162
|
+
// -------------------------
|
|
163
|
+
export default MegaPixImage
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
if (typeof module === 'object' && typeof module.exports === 'object') {
|
|
3
|
+
module.exports = factory() // CommonJS
|
|
4
|
+
} else if (typeof define === 'function' && define.amd) {
|
|
5
|
+
define([], factory) // AMD
|
|
6
|
+
} else {
|
|
7
|
+
global.MegaPixImage = factory() // Browser global
|
|
8
|
+
}
|
|
9
|
+
}(typeof window !== 'undefined' ? window : this, function () {
|
|
10
|
+
// -------------------------
|
|
11
|
+
// Helper functions
|
|
12
|
+
// -------------------------
|
|
13
|
+
function detectSubsampling (img) {
|
|
14
|
+
const iw = img.naturalWidth; const ih = img.naturalHeight
|
|
15
|
+
if (iw * ih > 1024 * 1024) {
|
|
16
|
+
const canvas = document.createElement('canvas')
|
|
17
|
+
canvas.width = canvas.height = 1
|
|
18
|
+
const ctx = canvas.getContext('2d')
|
|
19
|
+
ctx.drawImage(img, -iw + 1, 0)
|
|
20
|
+
return ctx.getImageData(0, 0, 1, 1).data[3] === 0
|
|
21
|
+
} else {
|
|
22
|
+
return false
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function detectVerticalSquash (img, iw, ih) {
|
|
27
|
+
const canvas = document.createElement('canvas')
|
|
28
|
+
canvas.width = 1
|
|
29
|
+
canvas.height = ih
|
|
30
|
+
const ctx = canvas.getContext('2d')
|
|
31
|
+
ctx.drawImage(img, 0, 0)
|
|
32
|
+
const data = ctx.getImageData(0, 0, 1, ih).data
|
|
33
|
+
let sy = 0; let ey = ih; let py = ih
|
|
34
|
+
while (py > sy) {
|
|
35
|
+
const alpha = data[(py - 1) * 4 + 3]
|
|
36
|
+
if (alpha === 0) { ey = py } else { sy = py }
|
|
37
|
+
py = (ey + sy) >> 1
|
|
38
|
+
}
|
|
39
|
+
const ratio = py / ih
|
|
40
|
+
return (ratio === 0) ? 1 : ratio
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function renderImageToDataURL (img, options, doSquash) {
|
|
44
|
+
const canvas = document.createElement('canvas')
|
|
45
|
+
renderImageToCanvas(img, canvas, options, doSquash)
|
|
46
|
+
return canvas.toDataURL('image/jpeg', options.quality || 0.8)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function renderImageToCanvas (img, canvas, options, doSquash) {
|
|
50
|
+
let iw = img.naturalWidth; let ih = img.naturalHeight
|
|
51
|
+
if (!(iw + ih)) return
|
|
52
|
+
const width = options.width; const height = options.height
|
|
53
|
+
const ctx = canvas.getContext('2d')
|
|
54
|
+
ctx.save()
|
|
55
|
+
transformCoordinate(canvas, ctx, width, height, options.orientation)
|
|
56
|
+
const subsampled = detectSubsampling(img)
|
|
57
|
+
if (subsampled) { iw /= 2; ih /= 2 }
|
|
58
|
+
const d = 1024
|
|
59
|
+
let tmpCanvas = document.createElement('canvas')
|
|
60
|
+
tmpCanvas.width = tmpCanvas.height = d
|
|
61
|
+
let tmpCtx = tmpCanvas.getContext('2d')
|
|
62
|
+
const vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1
|
|
63
|
+
const dw = Math.ceil(d * width / iw)
|
|
64
|
+
const dh = Math.ceil(d * height / ih / vertSquashRatio)
|
|
65
|
+
let sy = 0; let dy = 0
|
|
66
|
+
while (sy < ih) {
|
|
67
|
+
let sx = 0; let dx = 0
|
|
68
|
+
while (sx < iw) {
|
|
69
|
+
tmpCtx.clearRect(0, 0, d, d)
|
|
70
|
+
tmpCtx.drawImage(img, -sx, -sy)
|
|
71
|
+
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh)
|
|
72
|
+
sx += d; dx += dw
|
|
73
|
+
}
|
|
74
|
+
sy += d; dy += dh
|
|
75
|
+
}
|
|
76
|
+
ctx.restore()
|
|
77
|
+
tmpCanvas = tmpCtx = null
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function transformCoordinate (canvas, ctx, width, height, orientation) {
|
|
81
|
+
switch (orientation) {
|
|
82
|
+
case 5: case 6: case 7: case 8: canvas.width = height; canvas.height = width; break
|
|
83
|
+
default: canvas.width = width; canvas.height = height
|
|
84
|
+
}
|
|
85
|
+
switch (orientation) {
|
|
86
|
+
case 2: ctx.translate(width, 0); ctx.scale(-1, 1); break
|
|
87
|
+
case 3: ctx.translate(width, height); ctx.rotate(Math.PI); break
|
|
88
|
+
case 4: ctx.translate(0, height); ctx.scale(1, -1); break
|
|
89
|
+
case 5: ctx.rotate(0.5 * Math.PI); ctx.scale(1, -1); break
|
|
90
|
+
case 6: ctx.rotate(0.5 * Math.PI); ctx.translate(0, -height); break
|
|
91
|
+
case 7: ctx.rotate(0.5 * Math.PI); ctx.translate(width, -height); ctx.scale(-1, 1); break
|
|
92
|
+
case 8: ctx.rotate(-0.5 * Math.PI); ctx.translate(-width, 0); break
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const URL = window.URL && window.URL.createObjectURL
|
|
97
|
+
? window.URL
|
|
98
|
+
: window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL : null
|
|
99
|
+
|
|
100
|
+
// -------------------------
|
|
101
|
+
// MegaPixImage class
|
|
102
|
+
// -------------------------
|
|
103
|
+
function MegaPixImage (srcImage) {
|
|
104
|
+
if (window.Blob && srcImage instanceof Blob) {
|
|
105
|
+
if (!URL) { throw Error('No createObjectURL function found') }
|
|
106
|
+
const img = new Image()
|
|
107
|
+
img.src = URL.createObjectURL(srcImage)
|
|
108
|
+
this.blob = srcImage
|
|
109
|
+
srcImage = img
|
|
110
|
+
}
|
|
111
|
+
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
|
|
112
|
+
const _this = this
|
|
113
|
+
srcImage.onload = srcImage.onerror = function () {
|
|
114
|
+
const listeners = _this.imageLoadListeners
|
|
115
|
+
if (listeners) {
|
|
116
|
+
_this.imageLoadListeners = null
|
|
117
|
+
for (let i = 0; i < listeners.length; i++) { listeners[i]() }
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
this.imageLoadListeners = []
|
|
121
|
+
}
|
|
122
|
+
this.srcImage = srcImage
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
MegaPixImage.prototype.render = function (target, options, callback) {
|
|
126
|
+
if (this.imageLoadListeners) {
|
|
127
|
+
const _this = this
|
|
128
|
+
this.imageLoadListeners.push(function () { _this.render(target, options, callback) })
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
options = options || {}
|
|
132
|
+
const imgWidth = this.srcImage.naturalWidth; const imgHeight = this.srcImage.naturalHeight
|
|
133
|
+
let width = options.width; let height = options.height
|
|
134
|
+
const maxWidth = options.maxWidth; const maxHeight = options.maxHeight
|
|
135
|
+
const doSquash = !this.blob || this.blob.type === 'image/jpeg'
|
|
136
|
+
if (width && !height) { height = (imgHeight * width / imgWidth) << 0 } else if (height && !width) { width = (imgWidth * height / imgHeight) << 0 } else { width = imgWidth; height = imgHeight }
|
|
137
|
+
if (maxWidth && width > maxWidth) { width = maxWidth; height = (imgHeight * width / imgWidth) << 0 }
|
|
138
|
+
if (maxHeight && height > maxHeight) { height = maxHeight; width = (imgWidth * height / imgHeight) << 0 }
|
|
139
|
+
const opt = { width, height }
|
|
140
|
+
for (const k in options) opt[k] = options[k]
|
|
141
|
+
|
|
142
|
+
const tagName = target.tagName.toLowerCase()
|
|
143
|
+
if (tagName === 'img') { target.src = renderImageToDataURL(this.srcImage, opt, doSquash) } else if (tagName === 'canvas') { renderImageToCanvas(this.srcImage, target, opt, doSquash) }
|
|
144
|
+
if (typeof this.onrender === 'function') { this.onrender(target) }
|
|
145
|
+
if (callback) { callback() }
|
|
146
|
+
if (this.blob) { this.blob = null; URL.revokeObjectURL(this.srcImage.src) }
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// -------------------------
|
|
150
|
+
// Export as ESM default
|
|
151
|
+
// -------------------------
|
|
152
|
+
return MegaPixImage
|
|
153
|
+
}))
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* JavaScript EXIF Reader
|
|
3
|
+
* https://github.com/exif-js/exif-js
|
|
4
|
+
* 修复版:解决 strict mode 下未声明变量问题
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function () {
|
|
8
|
+
const debug = false
|
|
9
|
+
const root = this
|
|
10
|
+
|
|
11
|
+
const EXIF = function (obj) {
|
|
12
|
+
if (obj instanceof EXIF) return obj
|
|
13
|
+
if (!(this instanceof EXIF)) return new EXIF(obj)
|
|
14
|
+
this.EXIFwrapped = obj
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof exports !== 'undefined') {
|
|
18
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
19
|
+
exports = module.exports = EXIF
|
|
20
|
+
}
|
|
21
|
+
exports.EXIF = EXIF
|
|
22
|
+
} else {
|
|
23
|
+
root.EXIF = EXIF
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ========================= TAG MAPS ========================= */
|
|
27
|
+
|
|
28
|
+
const ExifTags = EXIF.Tags = {
|
|
29
|
+
0x9000: 'ExifVersion',
|
|
30
|
+
0xA000: 'FlashpixVersion',
|
|
31
|
+
0xA001: 'ColorSpace',
|
|
32
|
+
0xA002: 'PixelXDimension',
|
|
33
|
+
0xA003: 'PixelYDimension',
|
|
34
|
+
0x9101: 'ComponentsConfiguration',
|
|
35
|
+
0x9102: 'CompressedBitsPerPixel',
|
|
36
|
+
0x927C: 'MakerNote',
|
|
37
|
+
0x9286: 'UserComment',
|
|
38
|
+
0xA004: 'RelatedSoundFile',
|
|
39
|
+
0x9003: 'DateTimeOriginal',
|
|
40
|
+
0x9004: 'DateTimeDigitized',
|
|
41
|
+
0x9290: 'SubsecTime',
|
|
42
|
+
0x9291: 'SubsecTimeOriginal',
|
|
43
|
+
0x9292: 'SubsecTimeDigitized',
|
|
44
|
+
0x829A: 'ExposureTime',
|
|
45
|
+
0x829D: 'FNumber',
|
|
46
|
+
0x8822: 'ExposureProgram',
|
|
47
|
+
0x8824: 'SpectralSensitivity',
|
|
48
|
+
0x8827: 'ISOSpeedRatings',
|
|
49
|
+
0x8828: 'OECF',
|
|
50
|
+
0x9201: 'ShutterSpeedValue',
|
|
51
|
+
0x9202: 'ApertureValue',
|
|
52
|
+
0x9203: 'BrightnessValue',
|
|
53
|
+
0x9204: 'ExposureBias',
|
|
54
|
+
0x9205: 'MaxApertureValue',
|
|
55
|
+
0x9206: 'SubjectDistance',
|
|
56
|
+
0x9207: 'MeteringMode',
|
|
57
|
+
0x9208: 'LightSource',
|
|
58
|
+
0x9209: 'Flash',
|
|
59
|
+
0x920A: 'FocalLength',
|
|
60
|
+
0xA300: 'FileSource',
|
|
61
|
+
0xA301: 'SceneType',
|
|
62
|
+
0xA401: 'CustomRendered',
|
|
63
|
+
0xA402: 'ExposureMode',
|
|
64
|
+
0xA403: 'WhiteBalance',
|
|
65
|
+
0xA406: 'SceneCaptureType'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const TiffTags = EXIF.TiffTags = {
|
|
69
|
+
0x0100: 'ImageWidth',
|
|
70
|
+
0x0101: 'ImageHeight',
|
|
71
|
+
0x8769: 'ExifIFDPointer',
|
|
72
|
+
0x8825: 'GPSInfoIFDPointer',
|
|
73
|
+
0x0112: 'Orientation',
|
|
74
|
+
0x0132: 'DateTime',
|
|
75
|
+
0x010F: 'Make',
|
|
76
|
+
0x0110: 'Model',
|
|
77
|
+
0x0131: 'Software'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const GPSTags = EXIF.GPSTags = {
|
|
81
|
+
0x0000: 'GPSVersionID',
|
|
82
|
+
0x0001: 'GPSLatitudeRef',
|
|
83
|
+
0x0002: 'GPSLatitude',
|
|
84
|
+
0x0003: 'GPSLongitudeRef',
|
|
85
|
+
0x0004: 'GPSLongitude'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* ========================= CORE ========================= */
|
|
89
|
+
|
|
90
|
+
function getStringFromDB (buffer, start, length) {
|
|
91
|
+
let outstr = ''
|
|
92
|
+
let n
|
|
93
|
+
for (n = start; n < start + length; n++) {
|
|
94
|
+
outstr += String.fromCharCode(buffer.getUint8(n))
|
|
95
|
+
}
|
|
96
|
+
return outstr
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function readEXIFData (file, start) {
|
|
100
|
+
if (getStringFromDB(file, start, 4) !== 'Exif') {
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let bigEnd
|
|
105
|
+
const tiffOffset = start + 6
|
|
106
|
+
|
|
107
|
+
if (file.getUint16(tiffOffset) === 0x4949) {
|
|
108
|
+
bigEnd = false
|
|
109
|
+
} else if (file.getUint16(tiffOffset) === 0x4D4D) {
|
|
110
|
+
bigEnd = true
|
|
111
|
+
} else {
|
|
112
|
+
return false
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const firstIFDOffset = file.getUint32(tiffOffset + 4, !bigEnd)
|
|
116
|
+
const tags = readTags(file, tiffOffset, tiffOffset + firstIFDOffset, TiffTags, bigEnd)
|
|
117
|
+
|
|
118
|
+
if (tags.ExifIFDPointer) {
|
|
119
|
+
const exifData = readTags(
|
|
120
|
+
file,
|
|
121
|
+
tiffOffset,
|
|
122
|
+
tiffOffset + tags.ExifIFDPointer,
|
|
123
|
+
ExifTags,
|
|
124
|
+
bigEnd
|
|
125
|
+
)
|
|
126
|
+
let tag
|
|
127
|
+
for (tag in exifData) {
|
|
128
|
+
tags[tag] = exifData[tag]
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return tags
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function readTags (file, tiffStart, dirStart, strings, bigEnd) {
|
|
136
|
+
const entries = file.getUint16(dirStart, !bigEnd)
|
|
137
|
+
const tags = {}
|
|
138
|
+
let i
|
|
139
|
+
|
|
140
|
+
for (i = 0; i < entries; i++) {
|
|
141
|
+
const entryOffset = dirStart + i * 12 + 2
|
|
142
|
+
const tag = strings[file.getUint16(entryOffset, !bigEnd)]
|
|
143
|
+
if (tag) {
|
|
144
|
+
tags[tag] = readTagValue(file, entryOffset, tiffStart, bigEnd)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return tags
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function readTagValue (file, entryOffset, tiffStart, bigEnd) {
|
|
151
|
+
const type = file.getUint16(entryOffset + 2, !bigEnd)
|
|
152
|
+
const numValues = file.getUint32(entryOffset + 4, !bigEnd)
|
|
153
|
+
const valueOffset = file.getUint32(entryOffset + 8, !bigEnd) + tiffStart
|
|
154
|
+
let n, vals
|
|
155
|
+
|
|
156
|
+
if (type === 2) {
|
|
157
|
+
return getStringFromDB(file, valueOffset, numValues - 1)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (type === 3) {
|
|
161
|
+
if (numValues === 1) {
|
|
162
|
+
return file.getUint16(entryOffset + 8, !bigEnd)
|
|
163
|
+
}
|
|
164
|
+
vals = []
|
|
165
|
+
for (n = 0; n < numValues; n++) {
|
|
166
|
+
vals[n] = file.getUint16(valueOffset + 2 * n, !bigEnd)
|
|
167
|
+
}
|
|
168
|
+
return vals
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (type === 4) {
|
|
172
|
+
if (numValues === 1) {
|
|
173
|
+
return file.getUint32(entryOffset + 8, !bigEnd)
|
|
174
|
+
}
|
|
175
|
+
vals = []
|
|
176
|
+
for (n = 0; n < numValues; n++) {
|
|
177
|
+
vals[n] = file.getUint32(valueOffset + 4 * n, !bigEnd)
|
|
178
|
+
}
|
|
179
|
+
return vals
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return null
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function findEXIFinJPEG (file) {
|
|
186
|
+
const dataView = new DataView(file)
|
|
187
|
+
if (dataView.getUint8(0) !== 0xFF || dataView.getUint8(1) !== 0xD8) {
|
|
188
|
+
return false
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
let offset = 2
|
|
192
|
+
const length = file.byteLength
|
|
193
|
+
|
|
194
|
+
while (offset < length) {
|
|
195
|
+
if (dataView.getUint8(offset) !== 0xFF) {
|
|
196
|
+
return false
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const marker = dataView.getUint8(offset + 1)
|
|
200
|
+
if (marker === 225) {
|
|
201
|
+
return readEXIFData(
|
|
202
|
+
dataView,
|
|
203
|
+
offset + 4,
|
|
204
|
+
dataView.getUint16(offset + 2) - 2
|
|
205
|
+
)
|
|
206
|
+
} else {
|
|
207
|
+
offset += 2 + dataView.getUint16(offset + 2)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return false
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
EXIF.getData = function (img, callback) {
|
|
214
|
+
const reader = new FileReader()
|
|
215
|
+
reader.onload = function (e) {
|
|
216
|
+
img.exifdata = findEXIFinJPEG(e.target.result) || {}
|
|
217
|
+
if (callback) callback.call(img)
|
|
218
|
+
}
|
|
219
|
+
reader.readAsArrayBuffer(img)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
EXIF.getAllTags = function (img) {
|
|
223
|
+
return img.exifdata || {}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
EXIF.readFromBinaryFile = function (file) {
|
|
227
|
+
return findEXIFinJPEG(file)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (typeof define === 'function' && define.amd) {
|
|
231
|
+
define('exif-js', [], function () {
|
|
232
|
+
return EXIF
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
}.call(this))
|