create-playcanvas 0.2.6 → 0.4.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.
Files changed (103) hide show
  1. package/README.md +51 -47
  2. package/dist/index.mjs +49 -46
  3. package/package.json +54 -49
  4. package/templates/_shared/model-viewer/public/playcanvas-cube.glb +0 -0
  5. package/templates/engine/base/README.md +38 -0
  6. package/templates/engine/base/eslint.config.mjs +3 -0
  7. package/templates/engine/base/package.json +30 -0
  8. package/templates/engine/base/prettier.config.mjs +1 -0
  9. package/templates/engine/base/src/vite-env.d.ts +19 -0
  10. package/templates/engine/base/tsconfig.json +25 -0
  11. package/templates/engine/interactive-sphere/index.html +13 -0
  12. package/templates/engine/interactive-sphere/src/App.ts +180 -0
  13. package/templates/{vanilla-ts → engine/interactive-sphere}/src/main.ts +8 -8
  14. package/templates/engine/interactive-sphere/src/style.css +107 -0
  15. package/templates/engine/interactive-sphere/src/utils.ts +16 -0
  16. package/templates/engine/model-viewer/index.html +13 -0
  17. package/templates/engine/model-viewer/src/main.ts +81 -0
  18. package/templates/engine/model-viewer/src/style.css +8 -0
  19. package/templates/engine/spinning-cube/index.html +13 -0
  20. package/templates/engine/spinning-cube/src/main.ts +65 -0
  21. package/templates/engine/spinning-cube/src/style.css +8 -0
  22. package/templates/engine/splat-viewer/index.html +13 -0
  23. package/templates/engine/splat-viewer/src/main.ts +74 -0
  24. package/templates/engine/splat-viewer/src/style.css +8 -0
  25. package/templates/index.ts +47 -57
  26. package/templates/react/base/README.md +38 -0
  27. package/templates/react/base/eslint.config.mjs +14 -0
  28. package/templates/react/base/package.json +36 -0
  29. package/templates/react/base/prettier.config.mjs +1 -0
  30. package/templates/react/base/src/vite-env.d.ts +19 -0
  31. package/templates/react/base/tsconfig.json +26 -0
  32. package/templates/react/base/vite.config.ts +7 -0
  33. package/templates/react/interactive-sphere/index.html +13 -0
  34. package/templates/react/interactive-sphere/src/App.css +75 -0
  35. package/templates/react/interactive-sphere/src/App.tsx +43 -0
  36. package/templates/react/interactive-sphere/src/Scene.tsx +69 -0
  37. package/templates/react/interactive-sphere/src/index.css +51 -0
  38. package/templates/react/interactive-sphere/src/main.tsx +11 -0
  39. package/templates/react/model-viewer/index.html +13 -0
  40. package/templates/react/model-viewer/src/App.tsx +43 -0
  41. package/templates/react/model-viewer/src/index.css +9 -0
  42. package/templates/react/model-viewer/src/main.tsx +11 -0
  43. package/templates/react/spinning-cube/index.html +13 -0
  44. package/templates/react/spinning-cube/src/App.tsx +36 -0
  45. package/templates/react/spinning-cube/src/index.css +9 -0
  46. package/templates/react/spinning-cube/src/main.tsx +11 -0
  47. package/templates/react/splat-viewer/index.html +13 -0
  48. package/templates/react/splat-viewer/src/App.tsx +39 -0
  49. package/templates/react/splat-viewer/src/index.css +9 -0
  50. package/templates/react/splat-viewer/src/main.tsx +11 -0
  51. package/templates/web-components/base/README.md +66 -0
  52. package/templates/web-components/base/_gitignore +24 -0
  53. package/templates/web-components/base/eslint.config.mjs +3 -0
  54. package/templates/web-components/base/package.json +31 -0
  55. package/templates/web-components/base/prettier.config.mjs +1 -0
  56. package/templates/web-components/base/src/assets/playcanvas.png +0 -0
  57. package/templates/web-components/base/src/vite-env.d.ts +19 -0
  58. package/templates/web-components/base/tsconfig.json +25 -0
  59. package/templates/web-components/interactive-sphere/index.html +53 -0
  60. package/templates/web-components/interactive-sphere/src/assets/typescript.svg +1 -0
  61. package/templates/web-components/interactive-sphere/src/main.ts +76 -0
  62. package/templates/web-components/interactive-sphere/src/style.css +111 -0
  63. package/templates/web-components/model-viewer/index.html +34 -0
  64. package/templates/web-components/model-viewer/src/main.ts +26 -0
  65. package/templates/web-components/model-viewer/src/style.css +8 -0
  66. package/templates/web-components/spinning-cube/index.html +29 -0
  67. package/templates/web-components/spinning-cube/src/main.ts +20 -0
  68. package/templates/web-components/spinning-cube/src/style.css +8 -0
  69. package/templates/web-components/splat-viewer/index.html +31 -0
  70. package/templates/web-components/splat-viewer/src/main.ts +14 -0
  71. package/templates/web-components/splat-viewer/src/style.css +8 -0
  72. package/index.js +0 -3
  73. package/templates/react-ts/README.md +0 -82
  74. package/templates/react-ts/index.html +0 -13
  75. package/templates/react-ts/package.json +0 -29
  76. package/templates/react-ts/scripts/ensure-node-version.cjs +0 -12
  77. package/templates/react-ts/src/App.css +0 -87
  78. package/templates/react-ts/src/App.tsx +0 -46
  79. package/templates/react-ts/src/Scene.tsx +0 -70
  80. package/templates/react-ts/src/index.css +0 -73
  81. package/templates/react-ts/src/main.tsx +0 -10
  82. package/templates/react-ts/src/vite-env.d.ts +0 -1
  83. package/templates/react-ts/tsconfig.app.json +0 -27
  84. package/templates/react-ts/tsconfig.json +0 -7
  85. package/templates/react-ts/tsconfig.node.json +0 -25
  86. package/templates/react-ts/vite.config.ts +0 -7
  87. package/templates/vanilla-ts/README.md +0 -114
  88. package/templates/vanilla-ts/index.html +0 -13
  89. package/templates/vanilla-ts/package.json +0 -23
  90. package/templates/vanilla-ts/public/environment-map.png +0 -0
  91. package/templates/vanilla-ts/scripts/ensure-node-version.cjs +0 -12
  92. package/templates/vanilla-ts/src/App.ts +0 -182
  93. package/templates/vanilla-ts/src/style.css +0 -140
  94. package/templates/vanilla-ts/src/utils.ts +0 -16
  95. package/templates/vanilla-ts/src/vite-env.d.ts +0 -1
  96. package/templates/vanilla-ts/tsconfig.json +0 -25
  97. /package/templates/{react-ts → _shared/interactive-sphere}/public/environment-map.png +0 -0
  98. /package/templates/{react-ts → engine/base}/_gitignore +0 -0
  99. /package/templates/{react-ts → engine/base}/src/assets/playcanvas.png +0 -0
  100. /package/templates/{vanilla-ts → engine/interactive-sphere}/src/assets/typescript.svg +0 -0
  101. /package/templates/{vanilla-ts → react/base}/_gitignore +0 -0
  102. /package/templates/{vanilla-ts → react/base}/src/assets/playcanvas.png +0 -0
  103. /package/templates/{react-ts → react/interactive-sphere}/src/assets/react.svg +0 -0
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>PlayCanvas + TS</title>
8
- </head>
9
- <body>
10
- <div id="root"></div>
11
- <script type="module" src="/src/main.ts"></script>
12
- </body>
13
- </html>
@@ -1,23 +0,0 @@
1
- {
2
- "name": "playcanvas-project",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "predev": "node ./scripts/ensure-node-version.cjs",
8
- "dev": "vite",
9
- "build": "tsc && vite build",
10
- "preview": "vite preview"
11
- },
12
- "dependencies": {
13
- "playcanvas": "^2.17.2"
14
- },
15
- "devDependencies": {
16
- "semver": "^7.7.4",
17
- "typescript": "~6.0.2",
18
- "vite": "^8.0.8"
19
- },
20
- "engines": {
21
- "node": "^20.19.0 || >=22.12.0"
22
- }
23
- }
@@ -1,12 +0,0 @@
1
- const semver = require('semver');
2
- const pkg = require('../package.json');
3
-
4
- const requiredVersion = pkg.engines.node;
5
- const currentVersion = process.version;
6
-
7
- if (!semver.satisfies(currentVersion, requiredVersion)) {
8
- console.error(`\n❌ Unsupported Node.js version: ${currentVersion}`);
9
- console.error(`Required: ${requiredVersion}`);
10
- console.error('Please upgrade your Node.js to continue.\n');
11
- process.exit(1);
12
- }
@@ -1,182 +0,0 @@
1
- import {
2
- createGraphicsDevice,
3
- AppBase,
4
- AppOptions,
5
- RenderComponentSystem,
6
- CameraComponentSystem,
7
- ScriptComponentSystem,
8
- TextureHandler,
9
- ContainerHandler,
10
- FILLMODE_FILL_WINDOW,
11
- RESOLUTION_AUTO,
12
- Entity,
13
- Color,
14
- Vec3,
15
- Picker,
16
- EVENT_MOUSEMOVE,
17
- EVENT_MOUSEUP,
18
- TouchDevice,
19
- Mouse,
20
- MeshInstance,
21
- StandardMaterial,
22
- Layer,
23
- Asset,
24
- AssetListLoader,
25
- TEXTURETYPE_RGBP
26
- } from 'playcanvas';
27
-
28
- // @ts-expect-error - PlayCanvas ESM scripts don't have type declarations
29
- import { Grid } from 'playcanvas/scripts/esm/grid.mjs';
30
-
31
- // @ts-expect-error - PlayCanvas ESM scripts don't have type declarations
32
- import { CameraControls } from 'playcanvas/scripts/esm/camera-controls.mjs';
33
-
34
- import { throttle } from './utils';
35
-
36
- const HOVER_COLOR = new Color(1, 0.647, 0);
37
- const DEFAULT_COLOR = new Color(0.827, 0.827, 0.827);
38
-
39
- // Assets to load
40
- const assets = {
41
- envAtlas: new Asset('env-atlas', 'texture', { url: '/environment-map.png' }, {
42
- type: TEXTURETYPE_RGBP,
43
- mipmaps: false
44
- })
45
- };
46
-
47
- /**
48
- * Setup the PlayCanvas app
49
- * @param canvas - The canvas element
50
- * @param onClick - The function to call when the user clicks on the sphere
51
- */
52
- async function setupApp(canvas: HTMLCanvasElement, onClick: () => void) {
53
-
54
- if (!canvas) {
55
- throw new Error('Canvas not found');
56
- }
57
-
58
- // Create graphics device
59
- const device = await createGraphicsDevice(canvas);
60
-
61
- // Create app options
62
- const createOptions = new AppOptions();
63
- createOptions.graphicsDevice = device;
64
- createOptions.mouse = new Mouse(document.body);
65
- createOptions.touch = new TouchDevice(document.body);
66
- createOptions.componentSystems = [
67
- RenderComponentSystem,
68
- CameraComponentSystem,
69
- ScriptComponentSystem
70
- ];
71
- createOptions.resourceHandlers = [TextureHandler, ContainerHandler];
72
-
73
- // Create app
74
- const app = new AppBase(canvas);
75
- app.init(createOptions);
76
-
77
- // Set the canvas to fill the window
78
- app.setCanvasFillMode(FILLMODE_FILL_WINDOW);
79
- app.setCanvasResolution(RESOLUTION_AUTO);
80
-
81
- // Ensure canvas is resized when window changes size
82
- const resize = () => app.resizeCanvas();
83
- window.addEventListener('resize', resize);
84
-
85
- app.once('destroy', () => {
86
- window.removeEventListener('resize', resize);
87
- });
88
-
89
- // Load assets
90
- await new Promise<void>((resolve) => {
91
- new AssetListLoader(Object.values(assets), app.assets).load(() => resolve());
92
- });
93
-
94
- app.start();
95
-
96
- // Set up environment lighting (no skybox, just IBL)
97
- app.scene.envAtlas = assets.envAtlas.resource;
98
- const skyboxLayer = app.scene.layers.getLayerByName('Skybox');
99
- if (skyboxLayer) {
100
- skyboxLayer.enabled = false;
101
- }
102
-
103
- // Create sphere entity
104
- const sphere = new Entity('sphere');
105
- sphere.setPosition(new Vec3(0, 0.5, 0));
106
-
107
- // Create a new material
108
- const material = new StandardMaterial();
109
- material.diffuse.copy(DEFAULT_COLOR);
110
- material.update();
111
-
112
- sphere.addComponent('render', {
113
- type: 'sphere',
114
- material: material
115
- });
116
- app.root.addChild(sphere);
117
-
118
- // Create camera entity
119
- const camera = new Entity('camera');
120
- camera.addComponent('camera', {
121
- clearColor: new Color(0.09, 0.09, 0.09)
122
- });
123
- camera.setPosition(new Vec3(4, 1, 4));
124
- app.root.addChild(camera);
125
-
126
- // Create camera controls
127
- camera.addComponent('script');
128
- camera.script?.create(CameraControls);
129
-
130
- // Create grid entity
131
- const grid = new Entity('grid');
132
- grid.addComponent('script');
133
- grid.script?.create(Grid);
134
- grid.setLocalScale(1000, 1000, 1000);
135
- app.root.addChild(grid);
136
-
137
- // Create a picker for mouse interaction
138
- const picker = new Picker(app, 1, 1);
139
- const worldLayer = app.scene.layers.getLayerByName('World');
140
-
141
- const intersectsSphere = (x: number, y: number, layer: Layer): Promise<boolean> => {
142
- if (!camera.camera) {
143
- return Promise.resolve(false);
144
- }
145
-
146
- const pickerScale = 0.5;
147
- picker.resize(canvas.clientWidth * pickerScale, canvas.clientHeight * pickerScale);
148
-
149
- if (!layer) {
150
- return Promise.resolve(false);
151
- }
152
-
153
- picker.prepare(camera.camera, app.scene, [layer]);
154
-
155
- return picker.getSelectionAsync(x * pickerScale, y * pickerScale, 1, 1).then((meshInstances: MeshInstance[]): boolean => {
156
- if (meshInstances.length === 0) return false;
157
- return meshInstances[0] === sphere.render?.meshInstances[0];
158
- });
159
- };
160
-
161
- // On mouse move, check if hovering over sphere and update cursor/color
162
- app.mouse?.on(EVENT_MOUSEMOVE, throttle((event) => {
163
- if (!worldLayer) return;
164
- intersectsSphere(event.x, event.y, worldLayer).then((intersects) => {
165
- material.diffuse.copy(intersects ? HOVER_COLOR : DEFAULT_COLOR);
166
- document.body.style.cursor = intersects ? 'pointer' : 'default';
167
- material.update();
168
- });
169
- }, 100));
170
-
171
- // On mouse up, check if clicked on sphere and call onClick
172
- app.mouse?.on(EVENT_MOUSEUP, (event) => {
173
- if (!worldLayer || !onClick) return;
174
- intersectsSphere(event.x, event.y, worldLayer).then((intersects) => {
175
- if (intersects) {
176
- onClick();
177
- }
178
- });
179
- });
180
- }
181
-
182
- export { setupApp };
@@ -1,140 +0,0 @@
1
- :root {
2
- font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
3
- line-height: 1.5;
4
- font-weight: 400;
5
-
6
- color-scheme: light dark;
7
- color: rgba(255, 255, 255, 0.87);
8
- background-color: #242424;
9
-
10
- font-synthesis: none;
11
- text-rendering: optimizeLegibility;
12
- -webkit-font-smoothing: antialiased;
13
- -moz-osx-font-smoothing: grayscale;
14
- }
15
-
16
- header {
17
- display: flex;
18
- flex-direction: row;
19
- align-items: center;
20
- padding: 2rem;
21
- }
22
-
23
- a {
24
- font-weight: 500;
25
- color: #646cff;
26
- pointer-events: auto;
27
- text-decoration: inherit;
28
- }
29
- a:hover {
30
- color: #535bf2;
31
- }
32
-
33
- body {
34
- width: 100%;
35
- height: 100%;
36
- padding: 0;
37
- margin: 0;
38
- overflow: hidden;
39
- }
40
-
41
- h1 {
42
- font-size: 2.4em;
43
- line-height: 1.1;
44
- opacity: 0.85;
45
- }
46
-
47
- #app {
48
- max-width: 1280px;
49
- margin: 0 auto;
50
- padding: 2rem;
51
- text-align: center;
52
- }
53
-
54
- .logo {
55
- height: 2em;
56
- padding: .5em;
57
- will-change: filter;
58
- transition: filter 300ms;
59
- }
60
-
61
- .playcanvas-logo {
62
- border-radius: 100%;
63
- }
64
-
65
- .logo:hover {
66
- filter: drop-shadow(0 0 2em #646cffaa);
67
- }
68
-
69
- .logo.vanilla:hover {
70
- filter: drop-shadow(0 0 2em #3178c6aa);
71
- }
72
-
73
- .card {
74
- padding: 2em;
75
- }
76
-
77
- .read-the-docs {
78
- color: #888;
79
- }
80
-
81
- button {
82
- border-radius: 8px;
83
- border: 1px solid transparent;
84
- padding: 0.6em 1.2em;
85
- font-size: 1em;
86
- font-weight: 500;
87
- font-family: inherit;
88
- background-color: #1a1a1a;
89
- cursor: pointer;
90
- transition: border-color 0.25s;
91
- }
92
- button:hover {
93
- border-color: #646cff;
94
- }
95
- button:focus,
96
- button:focus-visible {
97
- outline: 4px auto -webkit-focus-ring-color;
98
- }
99
-
100
- @media (prefers-color-scheme: light) {
101
- :root {
102
- color: #213547;
103
- background-color: #ffffff;
104
- }
105
- a:hover {
106
- color: #747bff;
107
- }
108
- button {
109
- background-color: #f9f9f9;
110
- }
111
- }
112
-
113
- .overlay {
114
- margin: 0 auto;
115
- text-align: center;
116
- display: flex;
117
- flex-direction: column;
118
- align-items: center;
119
- justify-content: stretch;
120
- width: 100vw;
121
- height: 100vh;
122
- pointer-events: none;
123
- }
124
-
125
- .overlay > .grow {
126
- flex-grow: 1;
127
- }
128
-
129
- .absolute {
130
- position: absolute;
131
- top: 0;
132
- left: 0;
133
- }
134
-
135
- .pill {
136
- background-color: #000;
137
- color: #fff;
138
- padding: 0.5rem 1rem;
139
- border-radius: 0.5rem;
140
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Simple throttle helper
3
- * @param fn - The function to throttle
4
- * @param interval - The interval in milliseconds
5
- * @returns A throttled function
6
- */
7
- export function throttle(fn: (...args: any[]) => void, interval = 100) { // interval in ms
8
- let last = 0;
9
- return (...args: any[]) => {
10
- const now = Date.now();
11
- if (now - last >= interval) {
12
- last = now;
13
- fn(...args);
14
- }
15
- };
16
- }
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,25 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "useDefineForClassFields": true,
5
- "module": "ESNext",
6
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
7
- "skipLibCheck": true,
8
-
9
- /* Bundler mode */
10
- "moduleResolution": "bundler",
11
- "allowImportingTsExtensions": true,
12
- "verbatimModuleSyntax": true,
13
- "moduleDetection": "force",
14
- "noEmit": true,
15
-
16
- /* Linting */
17
- "strict": true,
18
- "noUnusedLocals": true,
19
- "noUnusedParameters": true,
20
- "erasableSyntaxOnly": true,
21
- "noFallthroughCasesInSwitch": true,
22
- "noUncheckedSideEffectImports": true
23
- },
24
- "include": ["src"]
25
- }
File without changes
File without changes