A browser source overlay for winter vibes for your Live Streams or Videos

Merge pull request #1 from ItzSulfur/main

Added contextMenu & settings page

Trey cb706926 1532dd22

+10 -1
index.html
···
<html lang="en">
<head>
<meta charset="UTF-8" />
-
<link rel="stylesheet" href="./src/style.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Winter Vibes JS</title>
</head>
<body>
<canvas id="main"></canvas>
<script type="module" src="./src/main.js"></script>
</body>
</html>
···
<html lang="en">
<head>
<meta charset="UTF-8" />
+
<link rel="stylesheet" href="./src/styles/main.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Winter Vibes JS</title>
</head>
<body>
<canvas id="main"></canvas>
+
+
<div id="contextMenu" class="context-menu" style="display:none">
+
<ul>
+
<li><a href="./src/pages/config.html">Settings</a></li>
+
<li><a href="https://github.com/TreyBastian/winterVibesJS/blob/main/README.md" target="_blank">Help</a></li>
+
<li><a href="https://buymeacoffee.com/treysdevshed" target="_blank">Buy me a coffee</a></li>
+
</ul>
+
</div>
+
<script type="module" src="./src/main.js"></script>
</body>
</html>
-10
pnpm-lock.yaml
···
.:
devDependencies:
-
typescript:
-
specifier: ^5.6.3
-
version: 5.6.3
vite:
specifier: ^5.4.10
version: 5.4.11
···
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
-
typescript@5.6.3:
-
resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
-
engines: {node: '>=14.17'}
-
hasBin: true
-
vite@5.4.11:
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
engines: {node: ^18.0.0 || >=20.0.0}
···
fsevents: 2.3.3
source-map-js@1.2.1: {}
-
-
typescript@5.6.3: {}
vite@5.4.11:
dependencies:
···
.:
devDependencies:
vite:
specifier: ^5.4.10
version: 5.4.11
···
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
vite@5.4.11:
resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==}
engines: {node: ^18.0.0 || >=20.0.0}
···
fsevents: 2.3.3
source-map-js@1.2.1: {}
vite@5.4.11:
dependencies:
+22
src/contextMenu.js
···
···
+
document.onclick = hideMenu;
+
document.oncontextmenu = rightClick;
+
+
function hideMenu() {
+
document.getElementById("contextMenu").style.display = "none"
+
}
+
+
function rightClick(e) {
+
e.preventDefault();
+
+
if (document.getElementById(
+
"contextMenu").style.display == "block")
+
hideMenu();
+
else {
+
let menu = document
+
.getElementById("contextMenu")
+
+
menu.style.display = 'block';
+
menu.style.left = e.pageX + "px";
+
menu.style.top = e.pageY + "px";
+
}
+
}
+33
src/getParams.js
···
···
+
window.addEventListener("DOMContentLoaded", () => {
+
const defaults = {
+
v: 1,
+
cw: 320,
+
ch: 180,
+
smx: 40,
+
smnsz: 1,
+
smxsz: 4,
+
smxspd: 0.07,
+
snmnspd: 0.04,
+
plwspd: 0.1,
+
plwd: "left",
+
plws: 1,
+
gamax: 4,
+
gas: 20
+
}
+
+
let params = {};
+
+
if (document.referrer.includes("/")) {
+
const indexParms = new URLSearchParams(new URL(document.referrer).search);
+
+
for (const [key, value] of indexParms.entries()) {
+
params[key] = value;
+
}
+
} else {
+
params = { ...defaults }
+
}
+
+
document.querySelectorAll("input").forEach(input => {
+
input.value = params[input.name] || "";
+
});
+
})
+1
src/main.js
···
resetSnowAccumulator,
} from "./snow_accumulator.js";
import { createPlow, drawPlow, movePlow, plowDone } from "./plow.js";
/**
* @type{Array.<Snowflake>}
···
resetSnowAccumulator,
} from "./snow_accumulator.js";
import { createPlow, drawPlow, movePlow, plowDone } from "./plow.js";
+
import "./contextMenu.js";
/**
* @type{Array.<Snowflake>}
+85
src/pages/config.html
···
···
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="UTF-8" />
+
<link rel="stylesheet" href="../styles/config.css" />
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
<title>Winter Vibes JS</title>
+
</head>
+
<body>
+
<div class="container">
+
+
<h1>Settings</h1>
+
+
<form action="../../index.html" method="get" class="form-container">
+
+
<input type="hidden" name="v" value="1">
+
+
<div class="settings-group">
+
<span class="title">Window</span>
+
<div class="separator"></div>
+
+
<label for="cw">Width</label>
+
<input type="number" name="cw" id="cw" placeholder="320" min="0" required>
+
+
<label for="ch">Height</label>
+
<input type="number" name="ch" id="ch" placeholder="180" min="0" required>
+
</div>
+
+
<div class="settings-group">
+
<span class="title">Snow</span>
+
<div class="separator"></div>
+
+
<label for="smx">Snow max</label>
+
<input type="number" name="smx" id="smx" placeholder="40" min="0" required>
+
+
<label for="smnsz">Snow min size</label>
+
<input type="number" name="smnsz" id="smnz" placeholder="1" min="0" required>
+
+
<label for="smxsz">Snow max size</label>
+
<input type="number" name="smxsz" id="smxsz" placeholder="4" min="0" required>
+
+
<label for="smxspd">Snow max speed</label>
+
<input type="number" step=".01" name="smxspd" id="smxspd" placeholder="0.07" required>
+
+
<label for="snmnspd">Snow min speed</label>
+
<input type="number" step=".01" name="snmnspd" id="snmnspd" placeholder="0.04" required>
+
</div>
+
+
<div class="settings-group">
+
<span class="title">Plow</span>
+
<div class="separator"></div>
+
+
<label for="plwspd">Plow speed</label>
+
<input type="number" step=".01" name="plwspd" id="plwspd" placeholder="0.1" required>
+
+
<label for="smnsz">Plow direction</label>
+
<select name="plwd" id="plwd" placeholder="right" required>
+
<option value="left">left</option>
+
<option value="right" disabled>right WIP</option>
+
<option value="random" disabled>random WIP</option>
+
</select>
+
+
<label for="plws">Plow scale</label>
+
<input type="number" name="plws" id="plws" placeholder="1" min="0" required>
+
</div>
+
+
<div class="settings-group">
+
<span class="title">Ground</span>
+
<div class="separator"></div>
+
+
<label for="gamax">Ground accumulator max</label>
+
<input type="number" name="gamax" id="gamax" placeholder="4" min="0" required>
+
+
<label for="gas">Ground accumulatior slices</label>
+
<input type="number" name="gas" id="gas" placeholder="20" min="0" required>
+
</div>
+
+
<button type="button" onclick="window.location.href='/'" style="color: red;">Default</button>
+
<button type="submit" value="submit" style="color: green;">Save</button>
+
</form>
+
</div>
+
+
<script type="module" src="../getParams.js"></script>
+
</body>
+
</html>
-22
src/style.css
···
-
*,
-
*:after,
-
*:befpre {
-
box-sizing: border-box;
-
}
-
-
body {
-
background-color: #091e36;
-
min-width: 100vw;
-
min-height: 100vh;
-
height: 100%;
-
width: 100%;
-
margin: 0;
-
padding: 0;
-
}
-
-
canvas {
-
background-color: transparent;
-
width: 100%;
-
height: 100%;
-
image-rendering: pixelated;
-
}
···
+90
src/styles/config.css
···
···
+
@import url('https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap');
+
+
* {
+
font-family: "Pixelify Sans", sans-serif;
+
font-style: normal;
+
}
+
+
body {
+
background-color: #091e36;
+
min-width: 100vw;
+
min-height: 100vh;
+
height: 100%;
+
width: 100%;
+
margin: 0;
+
padding: 0;
+
display: flex;
+
justify-content: center;
+
align-items: center;
+
}
+
+
h1 {
+
color: #e0e0e0;
+
font-weight: 100;
+
}
+
+
input {
+
border-radius: 10px;
+
border: 1px solid #555;
+
padding: 5px;
+
background-color: #1c2a3e;
+
color: #e0e0e0;
+
}
+
+
select {
+
border-radius: 10px;
+
padding: 5px;
+
border: 1px solid #555;
+
background-color: #1c2a3e;
+
color: #e0e0e0;
+
}
+
+
button {
+
border-radius: 10px;
+
padding: 5px;
+
background-color: #1e2a3a;
+
color: #e0e0e0;
+
border: 1px solid #555;
+
}
+
+
button:hover {
+
background-color: #273950;
+
cursor: pointer;
+
}
+
+
.form-container {
+
display: grid;
+
grid-template-columns: repeat(2, 1fr);
+
gap: 20px;
+
max-width: 600px;
+
width: 100%;
+
}
+
+
.settings-group {
+
width: 300px;
+
padding: 10px;
+
display: flex;
+
flex-direction: column;
+
border: 1px solid #555;
+
border-radius: 10px;
+
background-color: #1e2a3a;
+
color: #e0e0e0;
+
}
+
+
.container {
+
text-align: center;
+
width: 650px;
+
}
+
+
.title {
+
padding: 5px;
+
font-size: 20px;
+
color: #e0e0e0;
+
}
+
+
.separator {
+
width: 100%;
+
height: 1px;
+
background-color: #555;
+
margin: 10px 0;
+
}
+59
src/styles/main.css
···
···
+
@import url('https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap');
+
+
*,
+
*:after,
+
*:before {
+
box-sizing: border-box;
+
}
+
+
body {
+
font-family: "Pixelify Sans", sans-serif;
+
font-style: normal;
+
background-color: #091e36;
+
min-width: 100vw;
+
min-height: 100vh;
+
height: 100%;
+
width: 100%;
+
margin: 0;
+
padding: 0;
+
}
+
+
canvas {
+
background-color: transparent;
+
width: 100%;
+
height: 100%;
+
image-rendering: pixelated;
+
}
+
+
.context-menu {
+
border-radius: 10px;
+
position: absolute;
+
text-align: center;
+
background-color: #1e2a3a;
+
border: 1px solid #555;
+
}
+
+
.context-menu ul {
+
padding: 0px;
+
margin: 0px;
+
min-width: 150px;
+
list-style: none;
+
}
+
+
.context-menu ul li {
+
border-radius: 10px;
+
padding-bottom: 7px;
+
padding-top: 7px;
+
}
+
+
.context-menu ul li a {
+
border-radius: 10px;
+
text-decoration: none;
+
color: #e0e0e0;
+
display: block;
+
}
+
+
.context-menu ul li:hover {
+
border-radius: 10px;
+
background-color: #273950;
+
}
-8
vite.config.js
···
-
/**
-
* @type {import('vite').UserConfig}
-
*/
-
const config = {
-
publicDir: "assets",
-
};
-
-
export default config;
···