📡 Adds reactive data from socket connection
This commit is contained in:
@@ -1,26 +1,69 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import nipplejs from 'nipplejs';
|
import nipplejs from 'nipplejs';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { isPortrait } from '../lib/UseOrientation';
|
import { throttler } from '../lib/throttle';
|
||||||
|
|
||||||
|
let throttle = new throttler();
|
||||||
|
let left: nipplejs.JoystickManager;
|
||||||
|
let right: nipplejs.JoystickManager;
|
||||||
|
|
||||||
|
let throttle_timing = 50;
|
||||||
|
|
||||||
|
let left_vector = { x: 0, y: 0 };
|
||||||
|
let right_vector = { x: 0, y: 0 };
|
||||||
|
let height = 0; // -50 to 50
|
||||||
|
let speed = 0;
|
||||||
|
let mode = 'rest'; // 'rest' | 'stand' | 'stand+' | 'walk'
|
||||||
|
let stream_rotation = 0;
|
||||||
|
let temp = 0;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let left = nipplejs.create({
|
left = nipplejs.create({
|
||||||
zone: document.getElementById('left') as HTMLElement,
|
zone: document.getElementById('left') as HTMLElement,
|
||||||
color: 'grey',
|
color: 'grey',
|
||||||
dynamicPage: true,
|
dynamicPage: true,
|
||||||
mode: 'static'
|
mode: 'static'
|
||||||
});
|
});
|
||||||
let right = nipplejs.create({
|
|
||||||
|
left.on('move', (evt, data) => {
|
||||||
|
left_vector = data.vector;
|
||||||
|
throttle.throttle(updateData, throttle_timing);
|
||||||
|
});
|
||||||
|
|
||||||
|
left.on('end', (evt, data) => {
|
||||||
|
left_vector = { x: 0, y: 0 };
|
||||||
|
throttle.throttle(updateData, throttle_timing);
|
||||||
|
});
|
||||||
|
|
||||||
|
right = nipplejs.create({
|
||||||
zone: document.getElementById('right') as HTMLElement,
|
zone: document.getElementById('right') as HTMLElement,
|
||||||
color: 'grey',
|
color: 'grey',
|
||||||
dynamicPage: true,
|
dynamicPage: true,
|
||||||
mode: 'static'
|
mode: 'static'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
right.on('move', (evt, data) => {
|
||||||
|
right_vector = data.vector;
|
||||||
|
throttle.throttle(updateData, throttle_timing);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
right.on('end', (evt, data) => {
|
||||||
|
right_vector = { x: 0, y: 0 };
|
||||||
|
throttle.throttle(updateData, throttle_timing);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateData = () => {
|
||||||
|
console.log(height, left_vector, right_vector);
|
||||||
|
};
|
||||||
|
|
||||||
|
const lerp = (start: number, end: number, amt: number) => {
|
||||||
|
return (1 - amt) * start + amt * end;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="absolute top-0 left-0 w-screen h-screen">
|
<div class="absolute top-0 left-0 w-screen h-screen">
|
||||||
<div class="absolute top-0 left-0 h-full w-full flex {isPortrait ? 'hide' : ''}">
|
<div class="absolute top-0 left-0 h-full w-full flex portrait:hidden">
|
||||||
<div id="left" class="flex w-60 items-center justify-end" />
|
<div id="left" class="flex w-60 items-center justify-end" />
|
||||||
<div class="flex-1" />
|
<div class="flex-1" />
|
||||||
<div id="right" class="flex w-60 items-center" />
|
<div id="right" class="flex w-60 items-center" />
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { isConnected } from '../lib/socket';
|
import { isConnected, data } from '../lib/socket';
|
||||||
|
|
||||||
|
const toggleFullScreen = () => {
|
||||||
|
if (!document.fullscreenElement) document.documentElement.requestFullscreen();
|
||||||
|
else if (document.exitFullscreen) document.exitFullscreen();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="absolute top-0 flex justify-center w-full z-20">
|
<div class="absolute top-0 flex justify-between w-full z-20" on:dblclick={toggleFullScreen}>
|
||||||
|
<div class="w-20 p-2">☰</div>
|
||||||
|
<div class="flex justify-center">
|
||||||
<svg height="40" width="300" class="Settings_topSVG__2VXbU">
|
<svg height="40" width="300" class="Settings_topSVG__2VXbU">
|
||||||
<path stroke="none" fill="#36393f" d="M 0 0 C 40 0 40 40 80 40 H 220 C 260 40 260 0 300 0 Z" />
|
<path
|
||||||
|
stroke="none"
|
||||||
|
fill="#36393f"
|
||||||
|
d="M 0 0 C 40 0 40 40 80 40 H 220 C 260 40 260 0 300 0 Z"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<div
|
<div
|
||||||
class="absolute flex gap-1 h-10 w-36 justify-center items-center dots
|
class="absolute flex gap-1 h-10 w-36 justify-center items-center dots
|
||||||
@@ -16,6 +27,8 @@
|
|||||||
<span class="dot h-4 w-4" />
|
<span class="dot h-4 w-4" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w-20 p-2 text-right">{Math.floor($data[1])}°🌡️</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.dot {
|
.dot {
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
import { onMount } from "svelte";
|
|
||||||
import { writable, type Writable } from "svelte/store";
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
window.addEventListener("", () => {
|
|
||||||
screen.orientation.addEventListener("change", _handleOrientationChange);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
export type OrientationType = 'portrait-primary' | 'portrait-secondary' | 'landscape-primary' | 'landscape-secondary'
|
|
||||||
|
|
||||||
export const orientation:Writable<OrientationType> = writable('portrait-primary');
|
|
||||||
|
|
||||||
export const isPortrait = writable(true);
|
|
||||||
|
|
||||||
const _isPortrait = (orientation:OrientationType | undefined):boolean => {
|
|
||||||
return orientation === "portrait-primary" || orientation === "portrait-secondary";
|
|
||||||
}
|
|
||||||
|
|
||||||
const _handleOrientationChange = () => {
|
|
||||||
orientation.set(screen.orientation.type)
|
|
||||||
isPortrait.set(_isPortrait(screen.orientation.type))
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,8 @@ export type WebSocketStatus = 'OPEN' | 'CONNECTING' | 'CLOSED'
|
|||||||
|
|
||||||
export const isConnected = writable(false)
|
export const isConnected = writable(false)
|
||||||
|
|
||||||
|
export const data = writable(new Float32Array(13))
|
||||||
|
|
||||||
export const status:Writable<WebSocketStatus> = writable('CLOSED')
|
export const status:Writable<WebSocketStatus> = writable('CLOSED')
|
||||||
|
|
||||||
export const socket = writable(null)
|
export const socket = writable(null)
|
||||||
@@ -11,8 +13,10 @@ export const socket = writable(null)
|
|||||||
export const connect = (url:string) => {
|
export const connect = (url:string) => {
|
||||||
status.set('CONNECTING')
|
status.set('CONNECTING')
|
||||||
let _socket = new WebSocket(url);
|
let _socket = new WebSocket(url);
|
||||||
|
_socket.binaryType = "arraybuffer";
|
||||||
_socket.onopen = _connected;
|
_socket.onopen = _connected;
|
||||||
_socket.onclose = _disconnected;
|
_socket.onclose = _disconnected;
|
||||||
|
_socket.onmessage = _message;
|
||||||
socket.set(_socket)
|
socket.set(_socket)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,3 +30,9 @@ const _disconnected = () => {
|
|||||||
isConnected.set(false)
|
isConnected.set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _message = (event) => {
|
||||||
|
if (event.data instanceof ArrayBuffer) {
|
||||||
|
let buffer = new Uint8Array(event.data);
|
||||||
|
data.set(new Float32Array(buffer.buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
export class throttler {
|
||||||
|
private _throttlePause: boolean;
|
||||||
|
constructor() {
|
||||||
|
this._throttlePause = false;
|
||||||
|
}
|
||||||
|
throttle = (callback:Function, time:number) => {
|
||||||
|
if (this._throttlePause) return;
|
||||||
|
|
||||||
|
this._throttlePause = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
callback();
|
||||||
|
this._throttlePause = false;
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user