Skip to content

Commit 0e2ffc3

Browse files
committed
ping-viewer-next-frontend: Add Ping360 widget
1 parent 8094ff2 commit 0e2ffc3

File tree

7 files changed

+511
-393
lines changed

7 files changed

+511
-393
lines changed

ping-viewer-next-frontend/src/components/views/TryComponentView.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
import { ref } from 'vue'
2222
import DynamicForm from '../widgets/DynamicForm.vue'
2323
import DynamicFormGenerator from '../widgets/DynamicFormGenerator.vue'
24-
import Sonar360 from '../widgets/Sonar360.vue'
24+
import Ping360Loader from '../widgets/Ping360Loader.vue'
2525
import WebsocketClient from '../widgets/WebsocketClient.vue'
2626
import DevicesCardboard from '../widgets/DevicesCardboard.vue'
27-
import Sonar360Menu from '../widgets/Sonar360Menu.vue'
27+
import Sonar360Menu from '../widgets/Ping360Menu.vue'
2828
2929
const selectedComponent = ref('WebsocketClient')
3030
const isCollapsed = ref(false)
@@ -34,7 +34,7 @@ const components = {
3434
DevicesCardboard,
3535
DynamicFormGenerator,
3636
DynamicForm,
37-
Sonar360,
37+
Ping360Loader,
3838
Sonar360Menu
3939
}
4040
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<template>
2+
<div class="w-full h-full">
3+
<div class="relative w-full pb-[100%]">
4+
<div class="absolute inset-0">
5+
<template v-if="useMask">
6+
<SonarDisplayWrapper
7+
:angle="currentMeasurement?.angle ?? 0"
8+
:lineColor="lineColor"
9+
:lineWidth="lineWidth"
10+
:maxDistance="maxDistance"
11+
:numMarkers="numMarkers"
12+
:showRadiusLines="showRadiusLines"
13+
:showMarkers="showMarkers"
14+
:radiusLineColor="radiusLineColor"
15+
:markerColor="markerColor"
16+
:radiusLineWidth="radiusLineWidth"
17+
>
18+
<Sonar360
19+
:measurement="currentMeasurement"
20+
:numLines="400"
21+
:lineLength="1200"
22+
/>
23+
</SonarDisplayWrapper>
24+
</template>
25+
<template v-else>
26+
<Sonar360
27+
:measurement="currentMeasurement"
28+
:numLines="400"
29+
:lineLength="1200"
30+
/>
31+
</template>
32+
</div>
33+
</div>
34+
</div>
35+
</template>
36+
37+
<script setup lang="ts">
38+
import { ref, watch } from 'vue';
39+
import SonarDisplayWrapper from './sonar360/Sonar360Mask.vue';
40+
import Sonar360 from './sonar360/Sonar360Shader.vue';
41+
42+
interface SonarMeasurement {
43+
angle: number;
44+
data: Uint8Array;
45+
}
46+
47+
const props = withDefaults(defineProps<{
48+
measurement: SonarMeasurement | null;
49+
useMask?: boolean;
50+
lineColor?: string;
51+
lineWidth?: number;
52+
maxDistance?: number;
53+
numMarkers?: number;
54+
showRadiusLines?: boolean;
55+
showMarkers?: boolean;
56+
radiusLineColor?: string;
57+
markerColor?: string;
58+
radiusLineWidth?: number;
59+
}>(), {
60+
measurement: null,
61+
useMask: true,
62+
lineColor: 'red',
63+
lineWidth: 0.5,
64+
maxDistance: 300,
65+
numMarkers: 5,
66+
showRadiusLines: true,
67+
showMarkers: true,
68+
radiusLineColor: 'rgba(255,255,255,0.3)',
69+
markerColor: 'white',
70+
radiusLineWidth: 0.5
71+
});
72+
73+
const currentMeasurement = ref<SonarMeasurement | null>(null);
74+
75+
watch(() => props.measurement, (newMeasurement) => {
76+
if (newMeasurement) {
77+
currentMeasurement.value = newMeasurement;
78+
}
79+
});
80+
</script>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<template>
2+
<div class="flex bg-gray-100 p-6">
3+
<div class="max-w-4xl mx-auto bg-white shadow-lg rounded-lg overflow-hidden">
4+
<div class="bg-gray-800 text-white py-4 px-6">
5+
<h1 class="text-2xl font-bold">Ping Viewer Next - Sonar Display</h1>
6+
</div>
7+
8+
<div class="p-6">
9+
<h2 class="text-xl font-semibold mb-4">WebSocket Connection</h2>
10+
11+
<div class="flex items-center mb-6">
12+
<input v-model="websocketUrl" placeholder="Enter WebSocket URL"
13+
class="text-black flex-grow mr-2 p-2 border border-gray-300 rounded" />
14+
<button @click="toggleConnection"
15+
class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
16+
{{ isConnected ? 'Disconnect' : 'Connect' }}
17+
</button>
18+
</div>
19+
20+
<h2 class="text-xl font-semibold mb-4">Sonar Display</h2>
21+
22+
<div class="p-4 rounded">
23+
<Ping360
24+
:measurement="currentMeasurement"
25+
:maxDistance="300"
26+
:showMarkers="true"
27+
/>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
</template>
33+
34+
<script setup lang="ts">
35+
import { ref } from 'vue';
36+
import Ping360 from "./Ping360.vue";
37+
38+
interface SonarMeasurement {
39+
angle: number;
40+
data: Uint8Array;
41+
}
42+
43+
const websocketUrl = ref('ws://raulsyellowsubmarine2.duckdns.org:9997/ws?device_number=00000000-0000-0000-6113-f5df77d4fbd6');
44+
const socket = ref<WebSocket | null>(null);
45+
const isConnected = ref(false);
46+
const currentMeasurement = ref<SonarMeasurement | null>(null);
47+
48+
const toggleConnection = () => {
49+
if (isConnected.value) {
50+
disconnectWebSocket();
51+
} else {
52+
connectWebSocket();
53+
}
54+
};
55+
56+
const connectWebSocket = () => {
57+
if (socket.value) {
58+
socket.value.close();
59+
}
60+
61+
socket.value = new WebSocket(websocketUrl.value);
62+
63+
socket.value.addEventListener('open', () => {
64+
console.log('WebSocket connected.');
65+
isConnected.value = true;
66+
});
67+
68+
socket.value.addEventListener('close', () => {
69+
console.log('WebSocket closed.');
70+
isConnected.value = false;
71+
});
72+
73+
socket.value.addEventListener('error', (error) => {
74+
console.error('WebSocket error:', error);
75+
isConnected.value = false;
76+
});
77+
78+
socket.value.addEventListener('message', (event) => {
79+
const message = JSON.parse(event.data);
80+
const deviceData = message.DeviceMessage.PingMessage.Ping360.DeviceData;
81+
currentMeasurement.value = {
82+
angle: deviceData.angle,
83+
data: new Uint8Array(deviceData.data)
84+
};
85+
});
86+
};
87+
88+
const disconnectWebSocket = () => {
89+
if (socket.value) {
90+
socket.value.close();
91+
}
92+
};
93+
</script>

0 commit comments

Comments
 (0)