next-blurhash-previews 0.0.3-beta67 → 0.0.3-beta68
Sign up to get free protection for your applications and to get access to all the features.
package/bin/generateBlurhash.js
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import fs from "fs";
|
2
2
|
import path from "path";
|
3
|
+
import colors from "colors";
|
3
4
|
|
4
5
|
import sharp from "sharp";
|
5
6
|
import fetch from "node-fetch";
|
@@ -7,7 +8,7 @@ import { encode, isBlurhashValid } from "blurhash";
|
|
7
8
|
|
8
9
|
const __dirname = process.cwd();
|
9
10
|
|
10
|
-
|
11
|
+
async function getSharpImage(imgPath) {
|
11
12
|
if (/^http/.test(imgPath)) {
|
12
13
|
const buffer = await fetch(imgPath)
|
13
14
|
.then(fetchResponse => fetchResponse.arrayBuffer())
|
@@ -19,23 +20,33 @@ export async function getSharpImage(imgPath) {
|
|
19
20
|
const dir = path.dirname(imgPath);
|
20
21
|
const basename = path.basename(imgPath, ext);
|
21
22
|
|
23
|
+
const realImage = sharp(imgPath);
|
24
|
+
|
22
25
|
const previewOption = path.join(dir, basename + "-preview" + ext);
|
23
|
-
console.log("Trying preview", previewOption);
|
26
|
+
console.log(colors.blue("Trying preview", previewOption));
|
24
27
|
|
25
28
|
if (fs.existsSync(previewOption)) {
|
26
|
-
console.log("Preview found");
|
27
|
-
|
29
|
+
console.log(colors.green("Preview found"));
|
30
|
+
|
31
|
+
return [realImage, sharp(previewOption)];
|
28
32
|
}
|
29
33
|
|
30
|
-
return
|
34
|
+
return [realImage];
|
31
35
|
}
|
32
36
|
}
|
33
37
|
|
34
38
|
export async function getBlurhash(path) {
|
35
|
-
const blurhashImage = await getSharpImage(path);
|
39
|
+
const [blurhashImage, previewImage] = await getSharpImage(path);
|
36
40
|
const dimensions = await blurhashImage.metadata();
|
37
41
|
|
38
|
-
const { width, height } = dimensions;
|
42
|
+
const { width: displayWidth, height: displayHeight } = dimensions;
|
43
|
+
let { width, height } = dimensions;
|
44
|
+
|
45
|
+
if (previewImage) {
|
46
|
+
const dimensions = await previewImage.metadata();
|
47
|
+
|
48
|
+
({ width, height } = dimensions);
|
49
|
+
}
|
39
50
|
|
40
51
|
return new Promise((res, rej) => {
|
41
52
|
blurhashImage
|
@@ -54,7 +65,13 @@ export async function getBlurhash(path) {
|
|
54
65
|
4
|
55
66
|
);
|
56
67
|
if (isBlurhashValid(blurhash)) {
|
57
|
-
return res({
|
68
|
+
return res({
|
69
|
+
blurhash,
|
70
|
+
w: width,
|
71
|
+
h: height,
|
72
|
+
dw: displayWidth,
|
73
|
+
dh: displayHeight,
|
74
|
+
});
|
58
75
|
} else {
|
59
76
|
console.log("FAIL");
|
60
77
|
return rej("FAIL");
|
package/bin/remark-plugin.js
CHANGED
@@ -28,7 +28,7 @@ export const blurhashPlugin = publicPath => () => {
|
|
28
28
|
|
29
29
|
const blurHash = await getBlurhash(imagePath);
|
30
30
|
|
31
|
-
const { w, h } = blurHash;
|
31
|
+
const { w, h, dw, dh } = blurHash;
|
32
32
|
|
33
33
|
console.log(
|
34
34
|
colors.green(`Finished processing ${imagePath}\n\t`, blurHash)
|
@@ -40,7 +40,7 @@ export const blurhashPlugin = publicPath => () => {
|
|
40
40
|
const newNode = `
|
41
41
|
<blurhash-image url="${originalImg}" preview='${JSON.stringify(blurHash)}'>
|
42
42
|
<img alt="${alt}" width="${w}" height="${h}" src="${originalImg}" slot="image" />
|
43
|
-
<canvas width="${w}" height="${h}" slot="preview"></canvas>
|
43
|
+
<canvas width="${w}" height="${h}" style="width: ${dw}px; height: auto;" slot="preview"></canvas>
|
44
44
|
</blurhash-image>`.trim();
|
45
45
|
|
46
46
|
parent.children[index] = {
|
@@ -72,7 +72,11 @@ if (!customElements.get("blurhash-image")) {
|
|
72
72
|
customElements.define("blurhash-image", ImageWithPreview);
|
73
73
|
}
|
74
74
|
|
75
|
-
|
75
|
+
const workerBlob = new Blob(
|
76
|
+
[document.querySelector("#next-blurhash-worker-script")!.textContent!],
|
77
|
+
{ type: "text/javascript" }
|
78
|
+
);
|
79
|
+
const worker = new Worker(window.URL.createObjectURL(workerBlob));
|
76
80
|
|
77
81
|
function updateBlurHashPreview(canvasEl: HTMLCanvasElement, preview: blurhash) {
|
78
82
|
const { w: width, h: height, blurhash } = preview;
|
@@ -80,13 +84,6 @@ function updateBlurHashPreview(canvasEl: HTMLCanvasElement, preview: blurhash) {
|
|
80
84
|
canvasEl.height = height;
|
81
85
|
|
82
86
|
if (true) {
|
83
|
-
if (!worker) {
|
84
|
-
const workerBlob = new Blob(
|
85
|
-
[document.querySelector("#next-blurhash-worker-script")!.textContent!],
|
86
|
-
{ type: "text/javascript" }
|
87
|
-
);
|
88
|
-
worker = new Worker(window.URL.createObjectURL(workerBlob));
|
89
|
-
}
|
90
87
|
const offscreen = (canvasEl as any).transferControlToOffscreen();
|
91
88
|
worker.postMessage({ canvas: offscreen, width, height, blurhash }, [
|
92
89
|
offscreen,
|
@@ -3,12 +3,12 @@ import { createElement, Fragment } from "react";
|
|
3
3
|
export const imagePreviewBootstrap = createElement(
|
4
4
|
Fragment,
|
5
5
|
{},
|
6
|
-
createElement("script", {
|
7
|
-
dangerouslySetInnerHTML: { __html: `(() => { /*WC*/ })();` },
|
8
|
-
}),
|
9
6
|
createElement("script", {
|
10
7
|
id: "next-blurhash-worker-script",
|
11
8
|
type: "javascript/worker",
|
12
9
|
dangerouslySetInnerHTML: { __html: `(() => { /*WORKER*/ })();` },
|
10
|
+
}),
|
11
|
+
createElement("script", {
|
12
|
+
dangerouslySetInnerHTML: { __html: `(() => { /*WC*/ })();` },
|
13
13
|
})
|
14
14
|
);
|
package/imagePreviewBootstrap.js
CHANGED
@@ -3,94 +3,6 @@ import { createElement, Fragment } from "react";
|
|
3
3
|
export const imagePreviewBootstrap = createElement(
|
4
4
|
Fragment,
|
5
5
|
{},
|
6
|
-
createElement("script", {
|
7
|
-
dangerouslySetInnerHTML: { __html: `(() => { "use strict";
|
8
|
-
class ImageWithPreview extends HTMLElement {
|
9
|
-
sd;
|
10
|
-
mo;
|
11
|
-
static observedAttributes = ["preview"];
|
12
|
-
#connected = false;
|
13
|
-
get #imgEl() {
|
14
|
-
return this.querySelector("img");
|
15
|
-
}
|
16
|
-
get #canvasEl() {
|
17
|
-
return this.querySelector("canvas");
|
18
|
-
}
|
19
|
-
constructor() {
|
20
|
-
super();
|
21
|
-
this.sd = this.attachShadow({
|
22
|
-
mode: "open"
|
23
|
-
});
|
24
|
-
this.sd.innerHTML = \`<slot name="preview"></slot>\`;
|
25
|
-
}
|
26
|
-
#checkReady = () => {
|
27
|
-
if (this.#imgEl && this.#canvasEl) {
|
28
|
-
this.mo?.disconnect();
|
29
|
-
if (this.#imgEl.complete) {
|
30
|
-
this.#imgLoad();
|
31
|
-
} else {
|
32
|
-
this.#updatePreview();
|
33
|
-
this.#imgEl.addEventListener("load", this.#imgLoad);
|
34
|
-
}
|
35
|
-
return 1;
|
36
|
-
}
|
37
|
-
};
|
38
|
-
connectedCallback() {
|
39
|
-
this.#connected = true;
|
40
|
-
if (!this.#checkReady()) {
|
41
|
-
this.mo = new MutationObserver(this.#checkReady);
|
42
|
-
this.mo.observe(this, {
|
43
|
-
subtree: true,
|
44
|
-
childList: true,
|
45
|
-
attributes: false
|
46
|
-
});
|
47
|
-
}
|
48
|
-
}
|
49
|
-
#imgLoad = () => {
|
50
|
-
this.sd.innerHTML = \`<slot name="image"></slot>\`;
|
51
|
-
};
|
52
|
-
attributeChangedCallback(name) {
|
53
|
-
if (this.#canvasEl && name === "preview") {
|
54
|
-
this.#updatePreview();
|
55
|
-
}
|
56
|
-
}
|
57
|
-
#updatePreview() {
|
58
|
-
if (!this.#connected || !this.getAttribute("preview")) {
|
59
|
-
return;
|
60
|
-
}
|
61
|
-
const previewObj = JSON.parse(this.getAttribute("preview"));
|
62
|
-
updateBlurHashPreview(this.#canvasEl, previewObj);
|
63
|
-
}
|
64
|
-
}
|
65
|
-
if (!customElements.get("blurhash-image")) {
|
66
|
-
customElements.define("blurhash-image", ImageWithPreview);
|
67
|
-
}
|
68
|
-
var worker;
|
69
|
-
function updateBlurHashPreview(canvasEl, preview) {
|
70
|
-
const {
|
71
|
-
w: width,
|
72
|
-
h: height,
|
73
|
-
blurhash
|
74
|
-
} = preview;
|
75
|
-
canvasEl.width = width;
|
76
|
-
canvasEl.height = height;
|
77
|
-
{
|
78
|
-
if (!worker) {
|
79
|
-
const workerBlob = new Blob([document.querySelector("#next-blurhash-worker-script").textContent], {
|
80
|
-
type: "text/javascript"
|
81
|
-
});
|
82
|
-
worker = new Worker(window.URL.createObjectURL(workerBlob));
|
83
|
-
}
|
84
|
-
const offscreen = canvasEl.transferControlToOffscreen();
|
85
|
-
worker.postMessage({
|
86
|
-
canvas: offscreen,
|
87
|
-
width,
|
88
|
-
height,
|
89
|
-
blurhash
|
90
|
-
}, [offscreen]);
|
91
|
-
}
|
92
|
-
} })();` },
|
93
|
-
}),
|
94
6
|
createElement("script", {
|
95
7
|
id: "next-blurhash-worker-script",
|
96
8
|
type: "javascript/worker",
|
@@ -301,5 +213,90 @@ addEventListener("message", (evt) => {
|
|
301
213
|
const end = +new Date();
|
302
214
|
console.log("Done Encoding", blurhash, end - start);
|
303
215
|
}); })();` },
|
216
|
+
}),
|
217
|
+
createElement("script", {
|
218
|
+
dangerouslySetInnerHTML: { __html: `(() => { "use strict";
|
219
|
+
class ImageWithPreview extends HTMLElement {
|
220
|
+
sd;
|
221
|
+
mo;
|
222
|
+
static observedAttributes = ["preview"];
|
223
|
+
#connected = false;
|
224
|
+
get #imgEl() {
|
225
|
+
return this.querySelector("img");
|
226
|
+
}
|
227
|
+
get #canvasEl() {
|
228
|
+
return this.querySelector("canvas");
|
229
|
+
}
|
230
|
+
constructor() {
|
231
|
+
super();
|
232
|
+
this.sd = this.attachShadow({
|
233
|
+
mode: "open"
|
234
|
+
});
|
235
|
+
this.sd.innerHTML = \`<slot name="preview"></slot>\`;
|
236
|
+
}
|
237
|
+
#checkReady = () => {
|
238
|
+
if (this.#imgEl && this.#canvasEl) {
|
239
|
+
this.mo?.disconnect();
|
240
|
+
if (this.#imgEl.complete) {
|
241
|
+
this.#imgLoad();
|
242
|
+
} else {
|
243
|
+
this.#updatePreview();
|
244
|
+
this.#imgEl.addEventListener("load", this.#imgLoad);
|
245
|
+
}
|
246
|
+
return 1;
|
247
|
+
}
|
248
|
+
};
|
249
|
+
connectedCallback() {
|
250
|
+
this.#connected = true;
|
251
|
+
if (!this.#checkReady()) {
|
252
|
+
this.mo = new MutationObserver(this.#checkReady);
|
253
|
+
this.mo.observe(this, {
|
254
|
+
subtree: true,
|
255
|
+
childList: true,
|
256
|
+
attributes: false
|
257
|
+
});
|
258
|
+
}
|
259
|
+
}
|
260
|
+
#imgLoad = () => {
|
261
|
+
this.sd.innerHTML = \`<slot name="image"></slot>\`;
|
262
|
+
};
|
263
|
+
attributeChangedCallback(name) {
|
264
|
+
if (this.#canvasEl && name === "preview") {
|
265
|
+
this.#updatePreview();
|
266
|
+
}
|
267
|
+
}
|
268
|
+
#updatePreview() {
|
269
|
+
if (!this.#connected || !this.getAttribute("preview")) {
|
270
|
+
return;
|
271
|
+
}
|
272
|
+
const previewObj = JSON.parse(this.getAttribute("preview"));
|
273
|
+
updateBlurHashPreview(this.#canvasEl, previewObj);
|
274
|
+
}
|
275
|
+
}
|
276
|
+
if (!customElements.get("blurhash-image")) {
|
277
|
+
customElements.define("blurhash-image", ImageWithPreview);
|
278
|
+
}
|
279
|
+
const workerBlob = new Blob([document.querySelector("#next-blurhash-worker-script").textContent], {
|
280
|
+
type: "text/javascript"
|
281
|
+
});
|
282
|
+
const worker = new Worker(window.URL.createObjectURL(workerBlob));
|
283
|
+
function updateBlurHashPreview(canvasEl, preview) {
|
284
|
+
const {
|
285
|
+
w: width,
|
286
|
+
h: height,
|
287
|
+
blurhash
|
288
|
+
} = preview;
|
289
|
+
canvasEl.width = width;
|
290
|
+
canvasEl.height = height;
|
291
|
+
{
|
292
|
+
const offscreen = canvasEl.transferControlToOffscreen();
|
293
|
+
worker.postMessage({
|
294
|
+
canvas: offscreen,
|
295
|
+
width,
|
296
|
+
height,
|
297
|
+
blurhash
|
298
|
+
}, [offscreen]);
|
299
|
+
}
|
300
|
+
} })();` },
|
304
301
|
})
|
305
302
|
);
|