mirror of
https://github.com/Michatec/xhud.git
synced 2026-03-31 23:46:29 +02:00
First
This commit is contained in:
BIN
web/assets/images/logo.png
Normal file
BIN
web/assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
BIN
web/assets/sounds/buckle.ogg
Normal file
BIN
web/assets/sounds/buckle.ogg
Normal file
Binary file not shown.
BIN
web/assets/sounds/unbuckle.ogg
Normal file
BIN
web/assets/sounds/unbuckle.ogg
Normal file
Binary file not shown.
80
web/index.html
Normal file
80
web/index.html
Normal file
@@ -0,0 +1,80 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>xHUD</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
|
||||
integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w=="
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="Container">
|
||||
<div id="IconsContainer">
|
||||
<div id="Icons">
|
||||
<div id="VoiceIndicator" class="Icon">
|
||||
<i id="VoiceIcon" class="fas fa-times"></i>
|
||||
</div>
|
||||
|
||||
<div id="HealthIndicator" class="Icon">
|
||||
<i id="HealthIcon" class="fas fa-heart"></i>
|
||||
</div>
|
||||
|
||||
<div id="ArmourIndicator" class="Icon">
|
||||
<i id="ArmourIcon" class="fas fa-shield-alt"></i>
|
||||
</div>
|
||||
|
||||
<div id="StaminaIndicator" class="Icon">
|
||||
<i id="StaminaIcon" class="fas fa-running"></i>
|
||||
</div>
|
||||
|
||||
<div id="HungerIndicator" class="Icon">
|
||||
<i id="HungerIcon" class="fas fa-hamburger"></i>
|
||||
</div>
|
||||
|
||||
<div id="ThirstIndicator" class="Icon">
|
||||
<i id="ThirstIcon" class="fas fa-tint"></i>
|
||||
</div>
|
||||
|
||||
<div id="StressIndicator" class="Icon">
|
||||
<i id="StressIcon" class="fas fa-brain"></i>
|
||||
</div>
|
||||
|
||||
<div id="OxygenIndicator" class="Icon">
|
||||
<i id="OxygenIcon" class="fas fa-lungs"></i>
|
||||
</div>
|
||||
|
||||
<div id="FuelIndicator" class="Icon">
|
||||
<i id="FuelIcon" class="fas fa-gas-pump"></i>
|
||||
</div>
|
||||
|
||||
<div id="SpeedIndicator" class="Icon">
|
||||
<i id="SpeedIcon" class="fas fa-tachometer-alt"></i>
|
||||
</div>
|
||||
|
||||
<i id="SeatbeltIcon" class="fas fa-user-slash outerIcon"></i>
|
||||
|
||||
<div id="ID" class="outerIcon"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="Logo">
|
||||
<img src="assets/images/logo.png" alt="xHUD Logo" />
|
||||
</div>
|
||||
|
||||
<audio id="buckle" src="assets/sounds/buckle.ogg" preload></audio>
|
||||
<audio id="unbuckle" src="assets/sounds/unbuckle.ogg" preload></audio>
|
||||
<script
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/progressbar.js/0.6.1/progressbar.min.js"
|
||||
integrity="sha512-7IoDEsIJGxz/gNyJY/0LRtS45wDSvPFXGPuC7Fo4YueWMNOmWKMAllEqo2Im3pgOjeEwsOoieyliRgdkZnY0ow=="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script type="module" src="js/listener.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
66
web/js/circles.js
Normal file
66
web/js/circles.js
Normal file
@@ -0,0 +1,66 @@
|
||||
export default {
|
||||
HealthIndicator: new ProgressBar.Circle("#HealthIndicator", {
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
ArmourIndicator: new ProgressBar.Circle("#ArmourIndicator", {
|
||||
color: "rgb(0, 140, 255)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
StaminaIndicator: new ProgressBar.Circle("#StaminaIndicator", {
|
||||
color: "rgb(255, 255, 204)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
HungerIndicator: new ProgressBar.Circle("#HungerIndicator", {
|
||||
color: "rgb(255, 164, 59)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
ThirstIndicator: new ProgressBar.Circle("#ThirstIndicator", {
|
||||
color: "rgb(0, 140, 170)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
StressIndicator: new ProgressBar.Circle("#StressIndicator", {
|
||||
color: "rgb(255, 74, 104)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
OxygenIndicator: new ProgressBar.Circle("#OxygenIndicator", {
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
SpeedIndicator: new ProgressBar.Circle("#SpeedIndicator", {
|
||||
color: "rgb(255, 255, 255)",
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
FuelIndicator: new ProgressBar.Circle("#FuelIndicator", {
|
||||
trailColor: "rgb(35, 35, 35)",
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 600,
|
||||
}),
|
||||
VoiceIndicator: new ProgressBar.Circle("#VoiceIndicator", {
|
||||
strokeWidth: 13,
|
||||
trailWidth: 13,
|
||||
duration: 100,
|
||||
}),
|
||||
};
|
||||
251
web/js/listener.js
Normal file
251
web/js/listener.js
Normal file
@@ -0,0 +1,251 @@
|
||||
"use strict";
|
||||
import Circle from "./circles.js";
|
||||
|
||||
window.onload = (event) => {
|
||||
fetch(`https://${GetParentResourceName()}/nuiReady`);
|
||||
|
||||
const Container = document.getElementById("Container");
|
||||
const Logo = document.getElementById("Logo");
|
||||
const ID = document.getElementById("ID");
|
||||
|
||||
const Speed = document.getElementById("SpeedIndicator");
|
||||
const Fuel = document.getElementById("FuelIndicator");
|
||||
const Voice = document.getElementById("VoiceIndicator");
|
||||
const Armour = document.getElementById("ArmourIndicator");
|
||||
const Stamina = document.getElementById("StaminaIndicator");
|
||||
const Oxygen = document.getElementById("OxygenIndicator");
|
||||
const Health = document.getElementById("HealthIndicator");
|
||||
const Hunger = document.getElementById("HungerIndicator");
|
||||
const Thirst = document.getElementById("ThirstIndicator");
|
||||
const Stress = document.getElementById("StressIndicator");
|
||||
|
||||
const HealthIcon = document.getElementById("HealthIcon");
|
||||
const SpeedIcon = document.getElementById("SpeedIcon");
|
||||
const VoiceIcon = document.getElementById("VoiceIcon");
|
||||
const OxygenIcon = document.getElementById("OxygenIcon");
|
||||
const FuelIcon = document.getElementById("FuelIcon");
|
||||
const HungerIcon = document.getElementById("HungerIcon");
|
||||
const ThirstIcon = document.getElementById("ThirstIcon");
|
||||
const StressIcon = document.getElementById("StressIcon");
|
||||
|
||||
const Seatbelt = document.getElementById("SeatbeltIcon");
|
||||
const Buckle = document.getElementById("buckle");
|
||||
const Unbuckle = document.getElementById("unbuckle");
|
||||
|
||||
Circle.VoiceIndicator.animate(0.66);
|
||||
|
||||
window.addEventListener("message", function (event) {
|
||||
let action = event.data.action;
|
||||
let data = event.data.message;
|
||||
|
||||
if (action == "toggleHud") {
|
||||
Container.style.display = data ? "flex" : "none";
|
||||
}
|
||||
|
||||
if (action == "setLogo") {
|
||||
Logo.style.display = "block";
|
||||
}
|
||||
|
||||
if (action == "setPlayerId") {
|
||||
if (data) {
|
||||
ID.style.display = "block";
|
||||
ID.textContent = "#" + data;
|
||||
} else {
|
||||
ID.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
if (action == "setHealth") {
|
||||
Health.style.display = "block";
|
||||
|
||||
let health = (data.current - 100) / (data.max - 100);
|
||||
health < 0 && (health = 0);
|
||||
|
||||
if (health) {
|
||||
HealthIcon.classList.remove("fa-skull");
|
||||
HealthIcon.classList.add("fa-heart");
|
||||
} else {
|
||||
HealthIcon.classList.remove("fa-heart");
|
||||
HealthIcon.classList.add("fa-skull");
|
||||
}
|
||||
|
||||
Circle.HealthIndicator.trail.setAttribute(
|
||||
"stroke",
|
||||
health ? "rgb(35, 35, 35)" : "rgb(255, 0, 0)"
|
||||
);
|
||||
Circle.HealthIndicator.path.setAttribute(
|
||||
"stroke",
|
||||
health ? "rgb(0, 255, 100)" : "rgb(255, 0, 0)"
|
||||
);
|
||||
Circle.HealthIndicator.animate(health);
|
||||
}
|
||||
|
||||
if (action == "setArmour") {
|
||||
Armour.style.display = "block";
|
||||
Circle.ArmourIndicator.animate(data / 100, function () {
|
||||
Armour.style.display = data == 0 && "none";
|
||||
});
|
||||
}
|
||||
|
||||
if (action == "setStamina") {
|
||||
if (data) {
|
||||
Stamina.style.display = "block";
|
||||
|
||||
let stamina = data.current / data.max;
|
||||
stamina < 0 && (stamina = 0);
|
||||
stamina < 0.1 && StaminaIcon.classList.toggle("flash");
|
||||
|
||||
Circle.StaminaIndicator.path.setAttribute(
|
||||
"stroke",
|
||||
stamina < 0.1 ? "rgb(255, 0, 0)" : "rgb(255, 255, 200)"
|
||||
);
|
||||
Circle.StaminaIndicator.animate(stamina);
|
||||
} else {
|
||||
Circle.StaminaIndicator.animate(1, function () {
|
||||
Stamina.style.display = "none";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (action == "setOxygen") {
|
||||
if (data) {
|
||||
Oxygen.style.display = "block";
|
||||
|
||||
let oxygen = data.current / data.max;
|
||||
oxygen < 0 && (oxygen = 0);
|
||||
oxygen < 0.1 && OxygenIcon.classList.toggle("flash");
|
||||
|
||||
Circle.OxygenIndicator.path.setAttribute(
|
||||
"stroke",
|
||||
oxygen < 0.1 ? "rgb(255, 0, 0)" : "rgb(0, 140, 255)"
|
||||
);
|
||||
Circle.OxygenIndicator.animate(oxygen);
|
||||
} else {
|
||||
Circle.OxygenIndicator.animate(1, function () {
|
||||
Oxygen.style.display = "none";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (action == "setVehicle") {
|
||||
if (data) {
|
||||
Speed.style.display = "block";
|
||||
|
||||
let speed = data.speed.current * data.unitsMultiplier;
|
||||
let maxSpeed = data.speed.max * data.unitsMultiplier;
|
||||
let percSpeed = (speed / maxSpeed) * 0.7;
|
||||
let fuel = data.fuel && data.fuel / 100;
|
||||
|
||||
percSpeed > 1 && (percSpeed = 1);
|
||||
percSpeed >= 0.01 && SpeedIcon.classList.remove("fa-tachometer-alt");
|
||||
percSpeed >= 0.01 && (SpeedIcon.textContent = Math.floor(speed));
|
||||
percSpeed < 0.01 && SpeedIcon.classList.add("fa-tachometer-alt");
|
||||
percSpeed < 0.01 && (SpeedIcon.textContent = "");
|
||||
|
||||
if (data.electric == true) {
|
||||
FuelIcon.classList.remove("fa-gas-pump");
|
||||
FuelIcon.classList.add("fa-bolt");
|
||||
fuel = 1;
|
||||
} else {
|
||||
FuelIcon.classList.remove("fa-bolt");
|
||||
FuelIcon.classList.add("fa-gas-pump");
|
||||
}
|
||||
|
||||
Fuel.style.display = fuel !== false ? "block" : "none";
|
||||
fuel <= 0.15 && FuelIcon.classList.toggle("flash");
|
||||
Circle.FuelIndicator.path.setAttribute(
|
||||
"stroke",
|
||||
fuel > 0.15 ? "rgb(255, 255, 255)" : "rgb(255, 0, 0)"
|
||||
);
|
||||
|
||||
Circle.SpeedIndicator.animate(percSpeed);
|
||||
Circle.FuelIndicator.animate(fuel);
|
||||
} else {
|
||||
Circle.SpeedIndicator.animate(0, function () {
|
||||
Speed.style.display = "none";
|
||||
});
|
||||
Circle.FuelIndicator.animate(0, function () {
|
||||
Fuel.style.display = "none";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (action == "setVoice") {
|
||||
Voice.style.display = "block";
|
||||
if (data == "disconnected") {
|
||||
VoiceIcon.classList.remove("fa-microphone");
|
||||
VoiceIcon.classList.add("fa-times");
|
||||
Circle.VoiceIndicator.path.setAttribute("stroke", "rgb(255, 0, 0)");
|
||||
Circle.VoiceIndicator.trail.setAttribute("stroke", "rgb(255, 0, 0)");
|
||||
} else {
|
||||
VoiceIcon.classList.remove("fa-times");
|
||||
VoiceIcon.classList.add("fa-microphone");
|
||||
Circle.VoiceIndicator.path.setAttribute(
|
||||
"stroke",
|
||||
data ? "rgb(255, 255, 0)" : "rgb(169, 169, 169)"
|
||||
);
|
||||
Circle.VoiceIndicator.trail.setAttribute("stroke", "rgb(35, 35, 35)");
|
||||
}
|
||||
}
|
||||
|
||||
if (action == "setVoiceRange") {
|
||||
switch (data) {
|
||||
case 0:
|
||||
data = 15;
|
||||
break;
|
||||
case 1:
|
||||
data = 33;
|
||||
break;
|
||||
case 2:
|
||||
data = 66;
|
||||
break;
|
||||
case 3:
|
||||
data = 100;
|
||||
break;
|
||||
default:
|
||||
data = 33;
|
||||
break;
|
||||
}
|
||||
|
||||
Circle.VoiceIndicator.animate(data / 100);
|
||||
}
|
||||
|
||||
if (action == "status") {
|
||||
Hunger.style.display = "block";
|
||||
Thirst.style.display = "block";
|
||||
Stress.style.display = data.stress > 5 && "block";
|
||||
|
||||
data.hunger < 15 && HungerIcon.classList.toggle("flash");
|
||||
data.thirst < 15 && ThirstIcon.classList.toggle("flash");
|
||||
data.stress > 50 && StressIcon.classList.toggle("flash");
|
||||
|
||||
Circle.HungerIndicator.animate(data.hunger / 100);
|
||||
Circle.ThirstIndicator.animate(data.thirst / 100);
|
||||
Circle.StressIndicator.animate(data.stress / 100, function () {
|
||||
Stress.style.display = data.stress <= 5 && "none";
|
||||
});
|
||||
}
|
||||
|
||||
if (action == "setSeatbelt") {
|
||||
Seatbelt.style.display = data.toggled ? "block" : "none";
|
||||
Seatbelt.style.color = data.buckled
|
||||
? "rgb(0, 255, 100)"
|
||||
: "rgb(255, 100, 100)";
|
||||
}
|
||||
|
||||
if (action == "playSound") {
|
||||
switch (data) {
|
||||
case "unbuckle":
|
||||
Unbuckle.volume = 0.2;
|
||||
Unbuckle.play();
|
||||
break;
|
||||
case "buckle":
|
||||
Buckle.volume = 0.2;
|
||||
Buckle.play();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
97
web/style.css
Normal file
97
web/style.css
Normal file
@@ -0,0 +1,97 @@
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#Container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#IconsContainer {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
#Icons {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
margin: 20px 50px;
|
||||
}
|
||||
|
||||
.Icon {
|
||||
position: relative;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
background: rgb(50, 50, 50);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.Icon i {
|
||||
color: white;
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
/* Customisations */
|
||||
|
||||
#SpeedIcon:not(.fa-tachometer-alt) {
|
||||
font-family: sans-serif;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#ID {
|
||||
font-family: sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.outerIcon {
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
height: 50px;
|
||||
text-shadow: 1px 1px 10px #000;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Logo */
|
||||
|
||||
#Logo {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 40px;
|
||||
max-width: 128px;
|
||||
opacity: 0.8;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
|
||||
.flash {
|
||||
-webkit-animation: flash 1s;
|
||||
animation: flash 1s;
|
||||
}
|
||||
|
||||
@keyframes flash {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user