Преглед изворни кода

Introduce the Asset Manager

customisations
alemart пре 9 месеци
родитељ
комит
4b0f7e89b0
1 измењених фајлова са 108 додато и 0 уклоњено
  1. 108
    0
      plugins/extras/asset-manager.js

+ 108
- 0
plugins/extras/asset-manager.js Прегледај датотеку

@@ -0,0 +1,108 @@
1
+/**
2
+ * An Asset Manager for AR
3
+ * @author Alexandre Martins <alemartf(at)gmail.com> (https://github.com/alemart/encantar-js)
4
+ * @license LGPL-3.0-or-later
5
+ */
6
+
7
+/**
8
+ * The Asset Manager is used to preload resources (models, textures, etc.)
9
+ * You'll typically preload resources before starting the AR session
10
+ */
11
+class AssetManager
12
+{
13
+    /**
14
+     * Get an object URL corresponding to a preloaded asset
15
+     * @param {string} filename
16
+     * @returns {string}
17
+     * @throws Throws an error if the asset has not been successfully preloaded
18
+     */
19
+    url(filename)
20
+    {
21
+        return this._get(filename).url;
22
+    }
23
+
24
+    /**
25
+     * Get a File corresponding to a preloaded asset
26
+     * @param {string} filename
27
+     * @returns {File}
28
+     * @throws Throws an error if the asset has not been successfully preloaded
29
+     */
30
+    file(filename)
31
+    {
32
+        return this._get(filename).file;
33
+    }
34
+
35
+    /**
36
+     * Check if an asset has been preloaded successfully
37
+     * @param {string} filename
38
+     * @returns {boolean}
39
+     */
40
+    has(filename)
41
+    {
42
+        return this._assetMap.has(filename);
43
+    }
44
+
45
+    /**
46
+     * Preload one or more assets
47
+     * @param {string|string[]} url URL(s) of the asset(s)
48
+     * @returns {Promise<void>}
49
+     */
50
+    preload(url)
51
+    {
52
+        if(Array.isArray(url))
53
+            return Promise.all(url.map(url => this.preload(url)));
54
+
55
+        if(typeof url != 'string')
56
+            return Promise.reject(new TypeError());
57
+
58
+        const filename = url.substring(1 + url.lastIndexOf('/'));
59
+        if(this._assetMap.has(filename))
60
+            return Promise.resolve();
61
+
62
+        return new Promise(resolve => {
63
+            fetch(url)
64
+            .then(response => {
65
+                if(!response.ok)
66
+                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
67
+
68
+                return response.blob();
69
+            })
70
+            .then(blob => {
71
+                const file = new File([ blob ], filename, { type: blob.type });
72
+                const url = URL.createObjectURL(file);
73
+                const asset = { file, url };
74
+
75
+                this._assetMap.set(filename, asset);
76
+            })
77
+            .catch(error => {
78
+                console.warn(`Can't preload asset "${filename}"! ${error.message} (${url})`);
79
+            })
80
+            .finally(resolve);
81
+        });
82
+    }
83
+
84
+    /**
85
+     * Get a preloaded asset
86
+     * @param {string} filename
87
+     * @returns {object}
88
+     * @throws {Error}
89
+     * @internal
90
+     */
91
+    _get(filename)
92
+    {
93
+        const asset = this._assetMap.get(filename);
94
+
95
+        if(!asset)
96
+            throw new Error(`Asset "${filename}" has not been preloaded!`);
97
+
98
+        return asset;
99
+    }
100
+
101
+    /**
102
+     * Constructor
103
+     */
104
+    constructor()
105
+    {
106
+        this._assetMap = new Map();
107
+    }
108
+}

Loading…
Откажи
Сачувај