16 Commits

Author SHA1 Message Date
Janis
f403822921 v0.1.4 2022-10-31 18:30:29 +01:00
Janis
1c80395b5a localstorage theme 2022-10-31 18:30:22 +01:00
Janis
2ff402a320 v0.1.3 2022-10-31 17:38:52 +01:00
Janis
afacb9b93b added reward colors 2022-10-31 17:38:39 +01:00
Janis
271a7bc936 v0.1.2 2022-10-31 16:06:14 +01:00
Janis
63f113ec0b added particles 2022-10-31 16:06:03 +01:00
Janis
53555aad6a v0.1.1 2022-10-31 13:40:29 +01:00
Janis
a4f9697b6c add config 2022-10-30 15:49:21 +01:00
Janis
c0d72b8e43 remove cfg 2022-10-30 15:48:50 +01:00
Janis
80ea3c297e v0.1.0 2022-10-30 15:09:48 +01:00
Janis
c5e597ef58 added tf banner ;) 2022-10-30 15:09:35 +01:00
Janis
5dd6bbf290 v0.0.9 2022-10-29 17:12:44 +02:00
Janis
a45f99ecd3 v0.0.9 2022-10-29 17:12:10 +02:00
Janis
14079a997e v0.0.8 2022-10-29 16:53:39 +02:00
Janis
23044c320d v0.0.8 2022-10-29 16:53:35 +02:00
Janis
ae6d3f0ebf v0.0.7 2022-10-29 16:51:32 +02:00
22 changed files with 2212 additions and 33 deletions

1
.gitignore vendored
View File

@@ -1 +0,0 @@
config.js

View File

@@ -1,3 +1,32 @@
const CONFIG = {
apiKey: "",
twitch: {
username: "",
oAuth: "",
clientId: "",
rewardIds: {
turnRed: "",
turnGreen: "",
turnPurple: "",
turnBlue: "",
},
},
themes: {
red: {
0: "rgb(79, 6, 6)",
1: "rgb(247, 52, 52)",
},
green: {
0: "rgb(11, 69, 22)",
1: "rgb(88, 252, 170)",
},
purple: {
0: "rgb(62, 7, 66)",
1: "rgb(188, 79, 240)",
},
blue: {
0: "rgb(17, 11, 125)",
1: "rgb(61, 223, 255)",
},
},
};

View File

@@ -1,13 +1,5 @@
@keyframes subAnimation {
0% {
border-image: linear-gradient(
to top,
var(--border-color-1),
var(--border-color-2)
)
1;
}
10% {
border-image: linear-gradient(
to top,
var(--border-color-flash-1),
@@ -23,7 +15,7 @@
)
1;
}
80% {
100% {
border-image: linear-gradient(
to top,
var(--border-color-flash-1),
@@ -31,14 +23,6 @@
)
1;
}
100% {
border-image: linear-gradient(
to top,
var(--border-color-2),
var(--border-color-1)
)
1;
}
}
@keyframes borderAnimation {
@@ -82,18 +66,21 @@
@keyframes backgroundSubAnimation {
0% {
background: var(--border-color-1);
}
10% {
background: var(--border-color-flash-1);
}
50% {
background: var(--border-color-flash-2);
}
80% {
100% {
background: var(--border-color-flash-1);
}
100% {
background: var(--border-color-2);
}
@keyframes tfBannerAnimation {
from {
margin-top: -200px;
}
to {
margin-top: 0px;
}
}

View File

@@ -55,3 +55,34 @@ html {
animation-duration: 20s;
animation-name: backgroundAnimation;
}
#tealfire-banner {
height: 50px;
width: 180px;
padding: 20px;
margin-top: -200px;
z-index: 1;
animation-timing-function: linear;
float: right;
}
#tealfire-banner p {
color: teal;
float: left;
font-size: 23pt;
font-weight: bolder;
padding-top: 8px;
padding-left: 5px;
z-index: 5;
}
#tealfire-banner img {
color: teal;
height: 50px;
float: left;
}
#tealfire-banner .particles-js-canvas-el {
margin-top: -60px;
padding-bottom: 10px;
z-index: 0;
}

View File

@@ -1,7 +1,7 @@
:root {
--border-color-1: rgb(139, 0, 0);
--border-color-2: rgb(255, 74, 74);
--border-color-1: rgb(113, 0, 0);
--border-color-2: rgb(235, 19, 19);
--border-color-flash-1: rgb(220, 32, 15);
--border-color-flash-2: rgb(210, 220, 15);
--border-color-flash-1: rgb(255, 27, 6);
--border-color-flash-2: rgb(208, 218, 20);
}

View File

@@ -11,9 +11,17 @@
</head>
<body>
<div id="frame"></div>
<div id="tealfire-banner">
<img src="img/logo128x128.png" alt="" />
<p>TealFire</p>
</div>
<div id="subCount">0</div>
<div id="particles-frame"></div>
<script src="config.js"></script>
<script src="js/socket.io.min.js"></script>
<script src="js/modules/socket.io.min.js"></script>
<script src="js/modules/particles/particles.js"></script>
<script src="js/pubsub.js"></script>
<script src="js/app.js"></script>
<script src="js/socket.js"></script>
</body>

BIN
img/logo128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -1,5 +1,6 @@
const subCount = document.getElementById("subCount");
const frame = document.getElementById("frame");
const tfBanner = document.getElementById("tealfire-banner");
let subCountNumber = 0;
@@ -15,11 +16,13 @@ function updateSubCount() {
}
function sub(subName) {
particlesJS.load("particles-frame", "js/particles-sub.json");
frame.style.animationName = "subAnimation";
frame.style.animationDuration = "11s";
frame.style.animationDuration = "2s";
subCount.style.animationName = "backgroundSubAnimation";
subCount.style.animationDuration = "11s";
subCount.style.animationDuration = "2s";
subCount.innerText = subName + " " + subCountNumber;
@@ -31,6 +34,39 @@ function sub(subName) {
subCount.style.animationDuration = "20s";
subCount.innerText = subCountNumber;
updateSubCount();
particlesJS.load("particles-frame", "js/particles-none.json");
}, 11000);
}
function showTealFireBanner() {
tfBanner.style.animationName = "tfBannerAnimation";
tfBanner.style.animationDuration = "3s";
tfBanner.style.animationDirection = "normal";
setTimeout(() => {
tfBanner.style.marginTop = "0px";
tfBanner.style.animationName = "";
tfBanner.style.animationDuration = "";
}, 3000);
}
function closeTealFireBanner() {
tfBanner.style.animationName = "tfBannerAnimation";
tfBanner.style.animationDuration = "3s";
tfBanner.style.animationDirection = "reverse";
setTimeout(() => {
tfBanner.style.marginTop = "-200px";
tfBanner.style.animationName = "";
tfBanner.style.animationDuration = "";
}, 3000);
}
setInterval(() => {
showTealFireBanner();
setTimeout(() => {
closeTealFireBanner();
}, 20000); //20000
}, 300000); // 300000
updateSubCount();
particlesJS.load("tealfire-banner", "js/particles-banner.json");

View File

@@ -0,0 +1,22 @@
{
"name": "particles.js",
"main": "particles.js",
"version": "2.0.0",
"homepage": "https://github.com/VincentGarreau/particles.js",
"authors": [
"Vincent Garreau <vin.garreau@gmail.com>"
],
"description": "A lightweight JavaScript library for creating particles.",
"keywords": [
"particle",
"particles"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@@ -0,0 +1,28 @@
{
"name": "particles.js",
"version": "2.0.0",
"description": "A lightweight JavaScript library for creating particles",
"homepage": "http://vincentgarreau.com/particles.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/VincentGarreau/particles.js.git"
},
"keywords": [
"particles",
"particle",
"canvas"
],
"author": "Vincent Garreau",
"license": "MIT",
"files": [
"particles.js",
"particles.min.js"
],
"bugs": {
"url": "https://github.com/VincentGarreau/particles.js/issues"
},
"homepage": "https://github.com/VincentGarreau/particles.js"
}

File diff suppressed because it is too large Load Diff

9
js/modules/particles/particles.min.js vendored Normal file

File diff suppressed because one or more lines are too long

110
js/particles-banner.json Normal file
View File

@@ -0,0 +1,110 @@
{
"particles": {
"number": {
"value": 400,
"density": {
"enable": true,
"value_area": 100
}
},
"color": {
"value": "#00d680"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.7,
"random": true,
"anim": {
"enable": true,
"speed": 1,
"opacity_min": 0,
"sync": false
}
},
"size": {
"value": 2,
"random": true,
"anim": {
"enable": false,
"speed": 1,
"size_min": 0.3,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 150,
"color": "#d60e00",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 0.3,
"direction": "none",
"random": true,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 600
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 200,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 10,
"size": 0,
"duration": 2,
"opacity": 0,
"speed": 1
},
"repulse": {
"distance": 400,
"duration": 0.4
},
"push": {
"particles_nb": 2
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}

110
js/particles-none.json Normal file
View File

@@ -0,0 +1,110 @@
{
"particles": {
"number": {
"value": 0,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#fff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#fff"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0,
"random": true,
"anim": {
"enable": true,
"speed": 1,
"opacity_min": 0,
"sync": false
}
},
"size": {
"value": 0,
"random": true,
"anim": {
"enable": false,
"speed": 4,
"size_min": 0.3,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 150,
"color": "#d60e00",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 1,
"direction": "none",
"random": true,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 600
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 250,
"size": 0,
"duration": 2,
"opacity": 0,
"speed": 3
},
"repulse": {
"distance": 400,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}

110
js/particles-sub.json Normal file
View File

@@ -0,0 +1,110 @@
{
"particles": {
"number": {
"value": 200,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#d67d00"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 5
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 1,
"random": true,
"anim": {
"enable": true,
"speed": 2,
"opacity_min": 0,
"sync": false
}
},
"size": {
"value": 3,
"random": true,
"anim": {
"enable": false,
"speed": 2,
"size_min": 0.3,
"sync": false
}
},
"line_linked": {
"enable": false,
"distance": 150,
"color": "#d60e00",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 2,
"direction": "none",
"random": true,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": false,
"rotateX": 600,
"rotateY": 600
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": true,
"mode": "bubble"
},
"onclick": {
"enable": true,
"mode": "repulse"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 250,
"size": 0,
"duration": 2,
"opacity": 0,
"speed": 3
},
"repulse": {
"distance": 400,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}

108
js/pubsub.js Normal file
View File

@@ -0,0 +1,108 @@
const rootElem = document.querySelector(":root");
let ws;
let channelId;
function changeColorTheme(theme) {
localStorage.setItem("theme", JSON.stringify(theme));
rootElem.style.setProperty("--border-color-1", theme[0]);
rootElem.style.setProperty("--border-color-2", theme[1]);
}
function pubSubNonce(length) {
var text = "";
var possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
function pubSubHeartbeat() {
message = {
type: "PING",
};
ws.send(JSON.stringify(message));
}
function pubSubListen(topic) {
message = {
type: "LISTEN",
nonce: pubSubNonce(15),
data: {
topics: [topic],
auth_token: CONFIG.twitch.oAuth,
},
};
ws.send(JSON.stringify(message));
}
function pubSubConnect() {
var heartbeatInterval = 1000 * 60; //ms between PING's
var reconnectInterval = 1000 * 3; //ms to wait before reconnect
var heartbeatHandle;
ws = new WebSocket("wss://pubsub-edge.twitch.tv");
ws.onopen = function (event) {
console.log("PubSub Opened");
pubSubHeartbeat();
heartbeatHandle = setInterval(pubSubHeartbeat, heartbeatInterval);
pubSubListen("channel-points-channel-v1." + channelId);
};
ws.onerror = function (error) {
console.log("ERR: " + JSON.stringify(error) + "\n");
};
ws.onmessage = function (event) {
data = JSON.parse(event.data);
if (data.type == "MESSAGE") {
message = JSON.parse(data.data.message);
reward = message.data.redemption.reward;
console.log(`Received reward: ${reward.id} - ${reward.title}`);
switch (reward.id) {
case CONFIG.twitch.rewardIds.turnGreen:
changeColorTheme(CONFIG.themes.green);
break;
case CONFIG.twitch.rewardIds.turnPurple:
changeColorTheme(CONFIG.themes.purple);
break;
case CONFIG.twitch.rewardIds.turnRed:
changeColorTheme(CONFIG.themes.red);
break;
case CONFIG.twitch.rewardIds.turnBlue:
changeColorTheme(CONFIG.themes.blue);
break;
}
}
if (message.type == "RECONNECT") {
setTimeout(pubSubConnect, reconnectInterval);
}
};
ws.onclose = function () {
clearInterval(heartbeatHandle);
setTimeout(pubSubConnect, reconnectInterval);
};
}
function pubSubMain() {
fetch("https://api.twitch.tv/helix/users?login=" + CONFIG.twitch.username, {
headers: {
Authorization: "Bearer " + CONFIG.twitch.oAuth,
"Client-Id": CONFIG.twitch.clientId,
"Content-Type": "application/json",
},
})
.then((response) => response.json())
.then((resData) => {
channelId = resData.data[0].id;
pubSubConnect();
});
}
pubSubMain();
changeColorTheme(JSON.parse(localStorage.getItem("theme")));

View File

@@ -16,6 +16,7 @@ fetch("https://api.tipeeestream.com/v2.0/site/socket")
});
});
socket.on("new-event", (data) => {
console.log(data);
if (data.event.type == "subscription") {
sub(data.event.parameters.username);
}

View File

@@ -1,3 +1,3 @@
{
"version": "v0.0.6"
"version": "v0.1.4"
}

View File

@@ -32,7 +32,16 @@ if ($newestVersionString -ne "") {
else {
Write-Output "Updating to newer version..."
Remove-Item * -Recurse -Force -Confirm
if (Test-Path "./config.js") {
if (Test-Path "./config-old.js") {
Remove-Item config-old.js
}
Copy-Item "./config.js" -Destination "./config-old.js"
Write-Output "config.js has been copied"
}
Remove-Item * -Recurse -Force -Exclude config-old.js
mkdir ./temp
attrib +h ./temp

2
update_force.bat Normal file
View File

@@ -0,0 +1,2 @@
powershell ./update_force.ps1
pause

39
update_force.ps1 Normal file
View File

@@ -0,0 +1,39 @@
Write-Output "Starting update..."
$newestVersionString = ""
$req = Invoke-WebRequest https://github.com/DerTyp876/obs-twitch-camera-frame/releases/latest
foreach ($tag in $req.ParsedHtml.body.getElementsByTagName('h1')) {
if ($tag.innerText[0] -eq "v") {
$newestVersionString = $tag.innerText
}
}
Write-Output "Updating to newer version..."
if (Test-Path "./config.js") {
if (Test-Path "./config-old.js") {
Remove-Item config-old.js
}
Copy-Item "./config.js" -Destination "./config-old.js"
Write-Output "config.js has been copied"
}
Remove-Item * -Recurse -Force -Exclude config-old.js
mkdir ./temp
attrib +h ./temp
Write-Output "Downloading newer version..."
Invoke-WebRequest -Uri "https://github.com/DerTyp876/obs-twitch-camera-frame/archive/refs/tags/$newestVersionString.zip" -OutFile "./temp/$newestVersionString.zip"
Write-Output "Extracting archive..."
Expand-Archive -Path "./temp/$newestVersionString.zip" -DestinationPath "./temp/"
Get-ChildItem -Path "./temp/obs-twitch-camera-frame-$($newestVersionString -replace 'v')" -Recurse | Move-Item -Destination "./"
Remove-Item "./temp" -Recurse -Force -Confirm
Write-Output "You are now up to date again!"
Write-Output "You need to add your API-Key again to the config.js!"
pause