From 24a7862b35682e9808e90deb807f930572de3d3f Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 11:23:09 +0900 Subject: [PATCH 1/7] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index dcef93a..ce85f57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules dist tmp -.DS_Store \ No newline at end of file +.DS_Store +*.pem From 5c41b68cfd5d3ee71d024ac63d9205d1b66c24fa Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 11:25:46 +0900 Subject: [PATCH 2/7] Update README.md --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 2c28b40..af70d26 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,34 @@ This example uses image targets to display information about jellyfish on a flye 5. To connect to a mobile device, follow [these instructions](https://8th.io/test-on-mobile) 6. Recommended: Track your files using [git](https://git-scm.com/about) to avoid losing progress +## Serve projects over HTTPS + +Browsers require HTTPS certificates to access the camera. Use [http-server](https://github.com/http-party/http-server#readme) to serve project directories with HTTPS. + +First, you need to make sure that [openssl](https://github.com/openssl/openssl) is installed, and you have key.pem and cert.pem files. You can generate them using this command: + +``` +openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem +``` + +You will be prompted with a few questions after entering the command. Use 127.0.0.1 as value for Common name if you want to be able to install the certificate in your OS's root certificate store or browser so that it is trusted. + +This generates a cert-key pair and it will be valid for 3650 days (about 10 years). + +Then you can run `http-server` with `-S` for enabling SSL and `-C` for your certificate file: + +``` +npx http-server . -S -C cert.pem +``` + +**NOTE**: The first IP address listed is **127.0.0.1:8080** (which is the loopback +device aka "localhost") and your mobile phone won't be able to connect to that IP address directly. +Please use one of the other IP addresses. + +**WINDOWS USERS**: Run the http-server command using a standard Command Prompt window (cmd.exe). The script may generate errors if run from PowerShell. + +Learn more in the [http-server documentation](https://github.com/http-party/http-server#tlsssl). + ## Questions? Please raise any questions on [Github Discussions](https://github.com/orgs/8thwall/discussions) or join the [Discord](https://8th.io/discord) to connect with the community. From 625b29c4540d23bfd58393f080052b8dd5c71f34 Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 12:39:28 +0900 Subject: [PATCH 3/7] https --- config/webpack.config.js | 26 +++++++++++++++++++++++++- package-lock.json | 22 ++++++++-------------- src/app.js | 0 3 files changed, 33 insertions(+), 15 deletions(-) create mode 100644 src/app.js diff --git a/config/webpack.config.js b/config/webpack.config.js index 8c58cbe..3007478 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -1,3 +1,4 @@ +const fs = require('fs') const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') @@ -41,7 +42,8 @@ const makeSassLoader = () => ({ const makeAssetLoader = () => ({ test: /\..*$/, - include: [path.join(srcPath, 'assets')], + include: [path.join(srcPath, 'assets'), path.join(srcPath, 'targets')], + exclude: /\.(js|ts)$/, loader: path.join(__dirname, 'asset-loader.js'), }) @@ -101,6 +103,11 @@ const config = { to: path.join(distPath, 'image-targets'), noErrorOnMissing: true, }, + { + from: path.join(srcPath, 'targets'), + to: path.join(distPath, 'targets'), + noErrorOnMissing: true, + }, ], }), ], @@ -122,6 +129,23 @@ const config = { compress: true, hot: true, liveReload: false, + static: [ + { + directory: path.join(srcPath, 'targets'), + publicPath: '/targets', + }, + { + directory: path.join(srcPath, 'assets'), + publicPath: '/assets', + }, + ], + server: { + type: 'https', + options: { + key: fs.readFileSync(path.join(rootPath, 'key.pem')), + cert: fs.readFileSync(path.join(rootPath, 'cert.pem')), + }, + }, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', diff --git a/package-lock.json b/package-lock.json index 6769545..11a09f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -350,6 +350,7 @@ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, + "peer": true, "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" @@ -1546,6 +1547,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -2606,8 +2608,7 @@ "version": "16.18.126", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz", "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/qs": { "version": "6.14.0", @@ -2913,7 +2914,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2950,7 +2950,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4011,7 +4010,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4335,7 +4333,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/cookie": { "version": "0.7.2", @@ -5225,6 +5224,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "peer": true, "engines": { "node": ">=6.9.0" } @@ -6045,6 +6045,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -6671,7 +6672,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, - "peer": true, "engines": { "node": ">=12" }, @@ -6730,7 +6730,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -7209,7 +7208,6 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "dev": true, - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -8041,8 +8039,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tsyringe": { "version": "4.10.0", @@ -8080,7 +8077,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8240,7 +8236,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.3.tgz", "integrity": "sha512-LLBBA4oLmT7sZdHiYE/PeVuifOxYyE2uL/V+9VQP7YSYdJU7bSf7H8bZRRxW8kEPMkmVjnrXmoR3oejIdX0xbg==", "dev": true, - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -8289,7 +8284,6 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..e69de29 From 7c142367aefddc54de539b2f636a171c224dc28e Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 16:53:07 +0900 Subject: [PATCH 4/7] Update app.js --- src/app.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/app.js b/src/app.js index e69de29..6034512 100644 --- a/src/app.js +++ b/src/app.js @@ -0,0 +1,9 @@ +const onxrloaded = () => { + XR8.XrController.configure({ + imageTargetData: [ + require('targets/model-target.json'), + require('targets/video-target.json'), + ], + }) +} +window.XR8 ? onxrloaded() : window.addEventListener('xrloaded', onxrloaded) \ No newline at end of file From a1576f25b12149b039cae4f9ddb2b32e2d6154d2 Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 16:56:21 +0900 Subject: [PATCH 5/7] app bundle.js --- src/index.html | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/index.html b/src/index.html index 5f886ce..b594ac1 100644 --- a/src/index.html +++ b/src/index.html @@ -10,18 +10,8 @@ + - From a7372ed52a96ff81c55ebf41287b66b563bba80e Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 16:56:31 +0900 Subject: [PATCH 6/7] Image Target Assets --- src/targets/model-target-original.jpg | 3 --- src/targets/model-target.js | 16 ---------------- src/targets/model-target.json | 23 +++++++++++++++++++++++ src/targets/model-target_cropped.jpg | 3 +++ src/targets/model-target_luminance.jpg | 3 +++ src/targets/model-target_original.jpg | 3 +++ src/targets/model-target_thumbnail.jpg | 3 +++ src/targets/video-target-original.jpg | 3 --- src/targets/video-target.js | 16 ---------------- src/targets/video-target.json | 23 +++++++++++++++++++++++ src/targets/video-target_cropped.jpg | 3 +++ src/targets/video-target_luminance.jpg | 3 +++ src/targets/video-target_original.jpg | 3 +++ src/targets/video-target_thumbnail.jpg | 3 +++ 14 files changed, 70 insertions(+), 38 deletions(-) delete mode 100644 src/targets/model-target-original.jpg delete mode 100644 src/targets/model-target.js create mode 100644 src/targets/model-target.json create mode 100644 src/targets/model-target_cropped.jpg create mode 100644 src/targets/model-target_luminance.jpg create mode 100644 src/targets/model-target_original.jpg create mode 100644 src/targets/model-target_thumbnail.jpg delete mode 100644 src/targets/video-target-original.jpg delete mode 100644 src/targets/video-target.js create mode 100644 src/targets/video-target.json create mode 100644 src/targets/video-target_cropped.jpg create mode 100644 src/targets/video-target_luminance.jpg create mode 100644 src/targets/video-target_original.jpg create mode 100644 src/targets/video-target_thumbnail.jpg diff --git a/src/targets/model-target-original.jpg b/src/targets/model-target-original.jpg deleted file mode 100644 index 1b33c10..0000000 --- a/src/targets/model-target-original.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0c8356790e28147c467547fdac2c2361c6059dc0337025a525819c6fff99b9e9 -size 535054 diff --git a/src/targets/model-target.js b/src/targets/model-target.js deleted file mode 100644 index 4d06b64..0000000 --- a/src/targets/model-target.js +++ /dev/null @@ -1,16 +0,0 @@ -const imageTarget = { - "imagePath": "./model-target.jpg", - "metadata": {}, // available for custom use cases - "name": "model-target", - "type": "PLANAR", - "properties": { - "left": 0, - "top": 0, - "width": 480, - "height": 640, - "originalWidth": 995, - "originalHeight": 1326, - "isRotated": false, // set this to true if you rotated the image when you cropped it - } -} -export default imageTarget; \ No newline at end of file diff --git a/src/targets/model-target.json b/src/targets/model-target.json new file mode 100644 index 0000000..bb127cc --- /dev/null +++ b/src/targets/model-target.json @@ -0,0 +1,23 @@ +{ + "imagePath": "image-targets/model-target_luminance.jpg", + "metadata": null, + "name": "model-target", + "type": "PLANAR", + "properties": { + "left": 0, + "top": 0, + "width": 480, + "height": 640, + "isRotated": false, + "originalWidth": 480, + "originalHeight": 640 + }, + "resources": { + "originalImage": "model-target_original.jpg", + "croppedImage": "model-target_cropped.jpg", + "thumbnailImage": "model-target_thumbnail.jpg", + "luminanceImage": "model-target_luminance.jpg" + }, + "created": 1775116487722, + "updated": 1775116487723 +} diff --git a/src/targets/model-target_cropped.jpg b/src/targets/model-target_cropped.jpg new file mode 100644 index 0000000..e4d96db --- /dev/null +++ b/src/targets/model-target_cropped.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43710e22603ca2eef149ac6e239fb824c792379250db69162f2a0f734892db5c +size 43587 diff --git a/src/targets/model-target_luminance.jpg b/src/targets/model-target_luminance.jpg new file mode 100644 index 0000000..e4d96db --- /dev/null +++ b/src/targets/model-target_luminance.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43710e22603ca2eef149ac6e239fb824c792379250db69162f2a0f734892db5c +size 43587 diff --git a/src/targets/model-target_original.jpg b/src/targets/model-target_original.jpg new file mode 100644 index 0000000..e4d96db --- /dev/null +++ b/src/targets/model-target_original.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:43710e22603ca2eef149ac6e239fb824c792379250db69162f2a0f734892db5c +size 43587 diff --git a/src/targets/model-target_thumbnail.jpg b/src/targets/model-target_thumbnail.jpg new file mode 100644 index 0000000..15d5b86 --- /dev/null +++ b/src/targets/model-target_thumbnail.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3be1574ee2714cf85f740231003ab9abcc1c553ecba7324a7c6ec0c2318cd1a +size 14767 diff --git a/src/targets/video-target-original.jpg b/src/targets/video-target-original.jpg deleted file mode 100644 index 42852be..0000000 --- a/src/targets/video-target-original.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d1e1c9b123fc761c4d2e759736bea3dd61e40541ded21f62f137b8eafb9af981 -size 622920 diff --git a/src/targets/video-target.js b/src/targets/video-target.js deleted file mode 100644 index e369075..0000000 --- a/src/targets/video-target.js +++ /dev/null @@ -1,16 +0,0 @@ -const imageTarget = { - "imagePath": "./video-target.jpg", - "metadata": {}, // available for custom use cases - "name": "video-target", - "type": "PLANAR", - "properties": { - "left": 0, - "top": 0, - "width": 480, - "height": 640, - "originalWidth": 980, - "originalHeight": 1307, - "isRotated": false, // set this to true if you rotated the image when you cropped it - } -} -export default imageTarget; \ No newline at end of file diff --git a/src/targets/video-target.json b/src/targets/video-target.json new file mode 100644 index 0000000..65121e4 --- /dev/null +++ b/src/targets/video-target.json @@ -0,0 +1,23 @@ +{ + "imagePath": "image-targets/video-target_luminance.jpg", + "metadata": null, + "name": "video-target", + "type": "PLANAR", + "properties": { + "left": 0, + "top": 0, + "width": 480, + "height": 640, + "isRotated": false, + "originalWidth": 480, + "originalHeight": 640 + }, + "resources": { + "originalImage": "video-target_original.jpg", + "croppedImage": "video-target_cropped.jpg", + "thumbnailImage": "video-target_thumbnail.jpg", + "luminanceImage": "video-target_luminance.jpg" + }, + "created": 1775116530004, + "updated": 1775116530004 +} diff --git a/src/targets/video-target_cropped.jpg b/src/targets/video-target_cropped.jpg new file mode 100644 index 0000000..44d0550 --- /dev/null +++ b/src/targets/video-target_cropped.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b855022148d1eb4076b9d5a6f2fac5cd4f2bb5b6a0156588553907e0e62b294a +size 35999 diff --git a/src/targets/video-target_luminance.jpg b/src/targets/video-target_luminance.jpg new file mode 100644 index 0000000..44d0550 --- /dev/null +++ b/src/targets/video-target_luminance.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b855022148d1eb4076b9d5a6f2fac5cd4f2bb5b6a0156588553907e0e62b294a +size 35999 diff --git a/src/targets/video-target_original.jpg b/src/targets/video-target_original.jpg new file mode 100644 index 0000000..44d0550 --- /dev/null +++ b/src/targets/video-target_original.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b855022148d1eb4076b9d5a6f2fac5cd4f2bb5b6a0156588553907e0e62b294a +size 35999 diff --git a/src/targets/video-target_thumbnail.jpg b/src/targets/video-target_thumbnail.jpg new file mode 100644 index 0000000..d39708a --- /dev/null +++ b/src/targets/video-target_thumbnail.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e55c01bb30c4328685fb9bc05285da24725de36af3d2d071518a1c30ec066b28 +size 14100 From c12a7eca2638485ae34f4a3bfe2778d15f3abee5 Mon Sep 17 00:00:00 2001 From: Takeshi Kada Date: Thu, 2 Apr 2026 17:21:01 +0900 Subject: [PATCH 7/7] Configure webpack to support image target assets and module resolution - Add src/targets to resolve.modules so target files can be required without path prefix - Serve src/targets at /targets, /image-targets, and / via devServer.static - Exclude .json files from asset-loader to allow webpack native JSON parsing - Fix require paths in app.js to use short module names Made-with: Cursor --- config/webpack.config.js | 15 +++++++++++++-- src/app.js | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/config/webpack.config.js b/config/webpack.config.js index 3007478..9917756 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -43,7 +43,7 @@ const makeSassLoader = () => ({ const makeAssetLoader = () => ({ test: /\..*$/, include: [path.join(srcPath, 'assets'), path.join(srcPath, 'targets')], - exclude: /\.(js|ts)$/, + exclude: /\.(js|ts|json)$/, loader: path.join(__dirname, 'asset-loader.js'), }) @@ -111,7 +111,10 @@ const config = { ], }), ], - resolve: {extensions: ['.ts', '.js']}, + resolve: { + extensions: ['.ts', '.js'], + modules: [path.join(srcPath, 'targets'), 'node_modules'], + }, module: { rules: [ makeJsLoader(), @@ -134,6 +137,14 @@ const config = { directory: path.join(srcPath, 'targets'), publicPath: '/targets', }, + { + directory: path.join(srcPath, 'targets'), + publicPath: '/image-targets', + }, + { + directory: path.join(srcPath, 'targets'), + publicPath: '/', + }, { directory: path.join(srcPath, 'assets'), publicPath: '/assets', diff --git a/src/app.js b/src/app.js index 6034512..650f24f 100644 --- a/src/app.js +++ b/src/app.js @@ -1,8 +1,8 @@ const onxrloaded = () => { XR8.XrController.configure({ imageTargetData: [ - require('targets/model-target.json'), - require('targets/video-target.json'), + require('model-target.json'), + require('video-target.json'), ], }) }