-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathimage.js
94 lines (74 loc) · 3.39 KB
/
image.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import {
showInfoAlert,
showSuccessAlert,
showWarningAlert,
} from "@exabyte-io/cove.js/dist/other/alerts";
import { saveImageDataToFile } from "@exabyte-io/cove.js/dist/utils/downloader";
import { createGIFAsync } from "./utils";
export const ImageMixin = (superclass) =>
class extends superclass {
takeScreenshot() {
saveImageDataToFile(this.getScreenshotImage());
}
getScreenshotImage() {
const canvas = this.renderer.domElement;
canvas.getContext("2d", { willReadFrequently: true });
return canvas.toDataURL("image/png");
}
async updateScene() {
return new Promise((resolve) => {
const checkRender = () => {
this.renderer.render(this.scene, this.camera); // Ensure scene updates
requestAnimationFrame(() => resolve()); // Wait for the next frame
};
checkRender();
});
}
async createRotatingGifData(options = {}) {
const sampleInterval = options.sampleInterval || 20; // Parts of image in pixels
const totalGifDuration = options.totalDuration || 3; // Seconds
const animationDuration = options.animationDuration || 1; // Seconds
const totalFrames = options.totalFrames || 60; // Number of frames in GIF
const autoRotateSpeed = 60 / animationDuration; // RPM
const frameDuration = totalGifDuration / totalFrames;
const canvas = this.renderer.domElement;
canvas.willReadFrequently = true;
const { width, height } = canvas;
if (this.orbitControls.autoRotate) {
showWarningAlert("Please disable auto-rotation before creating a GIF.");
return null;
}
// Store original auto-rotate settings
const originalSpeed = this.orbitControls.autoRotateSpeed;
this.orbitControls.autoRotateSpeed = autoRotateSpeed;
this.orbitControls.autoRotate = true;
const frames = [];
for (let i = 0; i < totalFrames; i += 1) {
this.orbitControls.update(); // Move scene to new position
// eslint-disable-next-line no-await-in-loop
await this.updateScene(); // Wait for rendering to finish
frames.push(this.getScreenshotImage()); // Capture screenshot
}
showInfoAlert("GIF is being created. Please wait...");
const gifData = await createGIFAsync({
images: frames,
gifWidth: width,
gifHeight: height,
sampleInterval,
frameDuration,
});
// Restore original rotation settings
this.orbitControls.autoRotateSpeed = originalSpeed;
this.orbitControls.autoRotate = false;
canvas.willReadFrequently = false;
return gifData;
}
async takeGifScreenshot(options = {}) {
const gifDataUrl = await this.createRotatingGifData(options);
if (!gifDataUrl) return;
const fileName =
(this._structure.name || this._structure.formula || "wave-visualization") + ".gif";
showSuccessAlert("GIF is created. Proceeding to download.");
saveImageDataToFile(gifDataUrl, fileName);
}
};