Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/lib/components/Canvas.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
/** @param {Function} fn */
const run = (fn) => fn();

/**
* @description is required to rerender the scene if something has changed
*/
const invalidate = () => {
if (frame) return;

Expand Down
58 changes: 58 additions & 0 deletions src/lib/components/controls/PointerLockControls.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<script>
import { setup } from '../../utils/context.js';
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
import { createEventDispatcher } from 'svelte';

export let maxPolarAngle = Math.PI;
export let minPolarAngle = 0;

let isLocked = false;

const { root } = setup();
const dispatch = createEventDispatcher();

/** @type {PointerLockControls} */
let controls;

root.controls.set((camera, canvas) => {

controls = new PointerLockControls(camera, canvas);

controls.addEventListener('start', (e) => {
dispatch('start', e);
});

controls.addEventListener('end', (e) => {
dispatch('end', e);
});

controls.addEventListener('lock', (e) => {
isLocked = true;
dispatch('lock', e);
});

controls.addEventListener('unlock', (e) => {
isLocked = false;
dispatch('unlock', e);
});

// allows rotating the camera
controls.addEventListener('change', (e) => {
dispatch('change', e);

root.invalidate();
});

canvas.addEventListener('click', () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should remove all event listeners onDestroy https://svelte.dev/docs#onDestroy and also reset camera properties if needed

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it's not necessary, because the event listenders should get removed automatically as soon as the component is unmounted, because the object, on which the event listenters have been added to, doesn't exist any more.
If they really stay there I totally agree, that they should be removed.

In what case would you reset the camera properties? Either I am too sleepy or I haven't changed any camera properties in the current pull request?

controls.lock();
});

return controls;
});

$: if (controls) {
controls.isLocked = isLocked;
controls.maxPolarAngle = maxPolarAngle;
controls.minPolarAngle = minPolarAngle;
}
</script>
1 change: 1 addition & 0 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export { default as OrthographicCamera } from './components/cameras/Orthographic

// controls
export { default as OrbitControls } from './components/controls/OrbitControls.svelte';
export { default as PointerLockControls } from './components/controls/PointerLockControls.svelte';

// lights
export { default as AmbientLight } from './components/lights/AmbientLight.svelte';
Expand Down
41 changes: 41 additions & 0 deletions src/routes/examples/_content/03-first-person-camera/index.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script>
import * as THREE from 'three';
import * as SC from 'svelte-cubed';

let floor
let cube
</script>

<SC.Canvas
antialias
background={new THREE.Color('papayawhip')}
fog={new THREE.FogExp2('papayawhip', 0.1)}
shadows
>
<SC.Group position={[0, -1 / 2, 0]}>
<SC.Mesh
bind:this={floor}
geometry={new THREE.PlaneGeometry(50, 50)}
material={new THREE.MeshStandardMaterial({ color: 'burlywood' })}
rotation={[-Math.PI / 2, 0, 0]}
receiveShadow
/>
<SC.Primitive
object={new THREE.GridHelper(50, 50, 'papayawhip', 'papayawhip')}
position={[0, 0.001, 0]}
/>
</SC.Group>

<SC.Mesh
bind:this={cube}
geometry={new THREE.BoxGeometry()}
material={new THREE.MeshStandardMaterial({ color: 0xff3e00 })}
scale={[1, 1, 1]}
castShadow
/>

<SC.PerspectiveCamera position={[1, 1, 3]} />
<SC.PointerLockControls />
<SC.AmbientLight intensity={0.6} />
<SC.DirectionalLight intensity={0.6} position={[-2, 3, 2]} shadow={{ mapSize: [2048, 2048] }} />
</SC.Canvas>
3 changes: 3 additions & 0 deletions src/routes/examples/_content/03-first-person-camera/meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "First Person Controls"
}
Binary file added static/example-thumbnails/first-person-camera.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.