diff --git a/html/index.html b/html/index.html index 5f40c70..84a8576 100644 --- a/html/index.html +++ b/html/index.html @@ -2,63 +2,201 @@ 6bit.ch - + - - - - +
-
-
-
-
- +
+

+ +

The trajectory of this ship is unchanging.

- -
-
- -

The trajectory of this ship is unchanging.

-
- - -
-
-
+ +
+ + + +
+ +
+ ๐Ÿ‘พ qlpycon +
+
+					
+				
+

QLPyCon

+

Quake Live Python Console

+

Terminal-based client written in python for monitoring and controlling Quake Live servers via ZMQ

+
+ + +

- Real-time server monitoring with live feed of game events

+

- Server info display and full control via rcon

+

- Autocomplete cvars and commands with fuzzy matching

+

- Intelligent argument suggestions for 25+ commands

+

- Quake color code support (^0-^7)

+

- Command history & JSON event capture

+
+

License: WTFPL

+
+

pipe2bash (stable):

+
+

curl -sSL https://git.6bit.ch/xbl/qlpycon/raw/branch/main/install.sh | bash

+
+

git clone (edge):

+
+

git clone https://git.6bit.ch/xbl/qlpycon.git

+

cd qlpycon

+

chmod u+x install.sh

+

./install.sh

+
+
+
+ +
+ ๐ŸŽจ Things +
+
+ clicktoris.org +

clicktoris.org

+

image, logo

+
+
+ Hardbrugg.ch +

Hardbrugg.ch

+

image, logo

+
+
+ LeLAN +

LeLAN

+

image, logo

+
+
+
+ RAVE Rave +

RAVE Rave

+

image, postcard

+
+
+ RAVE Re-Rave +

RAVE Re-Rave

+

image, postcard

+
+
+ RAVE Fernbedienung Nebel +

RAVE Fernbedienung Nebel

+

image, postcard

+
+
+ RAVE Blazerstuhl des Lebens +

RAVE Blazerstuhl des Lebens

+

image, postcard

+
+
+ RAVE Durchgangskonzept +

RAVE Durchgangskonzept

+

image, postcard

+
+
+
+ C of Z +

C of Z

+

image, sticker

+
+
+ Gleis 1312 +

Gleis 1312

+

image, sticker

+
+
+ GrZH +

GrZH

+

image, sticker

+
+
+ planlos +

planlos

+

image, sticker

+
+
+ ViV +

ViV

+

image, sticker

+
+
+ ZBB +

ZBB

+

image, sticker

+
+
+
+ AlHo100 +

AlHo100

+

image, money

+
+
+ don't blender +

don't blender

+

image, 3d

+
+
+ EVE Online FaLiHSS +

EVE Online FaLiHSS (2006)

+

video, youtube

+
+
+ Postparade +

Postparade

+

pdf, text

+
+
+
+ +
+ ๐Ÿ Snek (arrow keys required) + +
+ +
- + + + + + + + + diff --git a/html/js/art.js b/html/js/art.js new file mode 100644 index 0000000..9346d17 --- /dev/null +++ b/html/js/art.js @@ -0,0 +1,369 @@ +const ARTS = [ + { + lines: [ + ' ____________________________________________________________________________', + ' ___/\\/\\/\\/\\____/\\/\\________/\\/\\______/\\/\\________________________/\\/\\_______', + ' _/\\/\\__________/\\/\\________________/\\/\\/\\/\\/\\__________/\\/\\/\\/\\__/\\/\\_______', + ' _/\\/\\/\\/\\/\\____/\\/\\/\\/\\____/\\/\\______/\\/\\____________/\\/\\________/\\/\\/\\/\\___', + ' _/\\/\\____/\\/\\__/\\/\\__/\\/\\__/\\/\\______/\\/\\______/\\/\\__/\\/\\________/\\/\\__/\\/\\_', + ' ___/\\/\\/\\/\\____/\\/\\/\\/\\____/\\/\\/\\____/\\/\\/\\____/\\/\\____/\\/\\/\\/\\__/\\/\\__/\\/\\_', + '____________________________________________________________________________' + ] + }, + { + lines: [ + ' @@@@@@ @@@@@@@ @@@ @@@@@@@ @@@@@@@ @@@ @@@ ', + ' @@@@@@@ @@@@@@@@ @@@ @@@@@@@ @@@@@@@@ @@@ @@@ ', + '!@@ @@! @@@ @@! @@! @@@ @@! @@@ ', + '!@! !@ @!@ !@! !@! !@! !@! @!@ ', + '!!@@!@! @!@!@!@ !!@ @!! !@! @!@!@!@! ', + '@!!@!!!! !!!@!!!! !!! !!! !!! !!!@!!!! ', + '!:! !:! !!: !!! !!: !!: :!! !!: !!! ', + ':!: !:! :!: !:! :!: :!: :!: :!: :!: !:! ', + ':::: ::: :: ::: :: :: ::: ::: ::: :: ::: ', + ' :: : : : : :: : : : :: :: : : :: ' + ] + }, + { + lines: [ + ' _____ _____ _____ _____ _____ _____ _____ ', + '|| ||| ||| ||| ||| ||| ||| ||', + '|| 6 ||| B ||| I ||| T ||| . ||| C ||| H ||', + '||_____|||_____|||_____|||_____|||_____|||_____|||_____||', + '|/_____\\|/_____\\|/_____\\|/_____\\|/_____\\|/_____\\|/_____\\|' + ] + }, + { + lines: [ + ' o__ __o o o o o ', + ' /v v\\ <|> _<|>_ <|> <|> ', + ' /> <\\ / > < > / > ', + ' \\o__ __o o | __o__ \\o__ __o ', + ' |__ _\\__o__ | v\\ <|> o__/_ /> \\ | v\\ ', + ' | \\ / \ <\\ / \\ | o/ / \\ <\\', + ' \\ / \\o/ / \\o/ | o <| \\o/ o/', + ' o o | o | o <|> \\\\ | <| ', + ' <\\__ __/> / \\ __/> / \\ <\\__ < > _\\o_____| /', + ' \\/ \\/ \\/ \\/ \\/ ' + ] + }, + { + lines: [ + '.eeeeee..eeeeeee..eee.eeeeeeeee......eeeee.eee..eee.', + '@@@@@@@@:@@@@@@@@:@@@:@@@@@@@@@:::::@@@@@@:@@@::@@@:', + '%%%------%%%--%%%-%%%----%%%--------%%%----%%%--%%%-', + '&&&&&&&++&&&&&&&++&&&++++&&&++++++++&&&++++&&&&&&&&+', + '||||||||*||||||||*|||****|||********|||****||||||||*', + '!!!==!!!=!!!==!!!=!!!====!!!========!!!====!!!==!!!=', + '::::::::#::::::::#:::####:::####:::#::::::#:::##:::#', + '@......@@.......@@...@@@@...@@@@...@@.....@...@@...@' + ] + }, + { + lines: [ + '`Yb .d .d `Yb. ', + ' `8 db P\' P\' `Yb ', + ' 8 Yb ', + ' 88888888888b. `Yb d88b d88b \'Yb `Yb.d888b .dP\' dP\' Yb ', + ' 8 .P\' .P\' 88P 8Y 8b 88 88\' 8Y 88 88 dPYb ', + ' .P 8 8 b 88 8P 88 88 88 8P .d .d Y8 .88 ,dP Yb ', + ' .P\' `Ybd`YbwP\' 88 .dP\' .dP\' .8P 88 ,dP P\' P\' `Y88P\'88 .dP\' `Yb.', + ' 8 b 888888888888b. 88 88 ', + ' `YbwP\' 88 88 88 ', + ' .8P .8P Y8. ' + ] + }, + { + lines: [ + '#### #### # # ##### # # # #', + '# # # ## # # # # # ', + '#### #### # # # # #### # ', + '# # # # ## # # # # # ', + '#### ##### # # # # # # #' + + ] + }, + { + lines: [ + ' _____ __ _ __ __ ', + ' / ___// /_ (_) /_ _____/ /_ ', + ' / __ \\/ __ \\/ / __// ___/ __ \\', + '/ /_/ / /_/ / / /__/ /__/ / / /', + '\\____/_.___/_/\\__(_)___/_/ /_/ ' + ] + }, + { + lines: [ + ' _ _ _ _ _ _ _ ', + ' _(_)(_)(_) (_) (_) (_) (_) ', + ' _(_) (_) _ _ _ _ _ _ (_) _ _ _ _ _ (_) _ _ _ ', + '(_) _ _ _ (_)(_)(_)(_)_ (_)(_)(_)(_)(_)(_) _(_)(_)(_)(_)(_)(_)(_)_ ', + '(_)(_)(_)(_)_ (_) (_) (_) (_) (_) (_) (_)', + '(_) (_)(_) (_) (_) (_) _ _ _ (_) (_) (_)', + '(_)_ _ _ (_)(_) _ _ _(_) _ (_) _ (_)_ _(_) (_)(_) (_)_ _ _ (_) (_)', + ' (_)(_)(_) (_)(_)(_)(_) (_)(_)(_) (_)(_) (_)(_) (_)(_)(_)(_) (_)' + ] + }, + { + lines: [ + ' {__ {__ ', + ' {__ {__ {__ {__ {__ ', + ' {__ {__ {_{_ {_ {__ ', + ' {__ {__ {__ {__ {__ {___{__{_ ', + '{_ {__ {__ {__{__ {__ {__ {__ {__', + '{__ {__{__ {__{__ {__ {__ {__ {__', + ' {___{__ {___{__ {__ {___{__{___{__ {__' + ] + }, + { + lines: [ + ' `.. `.. ', + ' `.. `.. `. `.. `.. ', + ' `.. `.. .`. `. `...`.. ', + ' `.. `.. `.. `.. `.. `.. `. `. ', + '`. `.. `.. `..`.. `.. `.. `.. `..', + '`.. `..`.. `. `.. `.. `.. `. `..', + ' `.. ..` `.. ..` `.. `.. `.. `...`.. `..' + ] + }, + { + lines: [ + ' :::::::: ::::::::: ::::::::::::::: :::::::: ::: :::', + ':+: :+: :+: :+: :+: :+: :+: :+: :+: :+:', + '+:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+', + '+#++:++#+ +#++:++#+ +#+ +#+ +#+ +#++:++#++', + '+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+', + '#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+#', + ' ######## ######### ####### ### ### ######## ### ###' + ] + }, + { + lines: [ + ' dD d8888b. d888888b d888888b .o88b. db db', + ' d8\' 88 `8D `88\' `~~88~~\' d8P Y8 88 88', + ' d8\' 88oooY\' 88 88 8P 88ooo88', + 'd8888b. 88~~~b. 88 88 8b 88~~~88', + '88\' `8D 88 8D .88. 88 db Y8b d8 88 88', + '`8888P Y8888P\' Y888888P YP VP `Y88P\' YP YP' + ] + }, + { + lines: [ + '-....', + '-...', + '..', + '-', + '.-.-.-', + '-.-.', + '....' + ] + }, + { + lines: [ + ' โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ ', + ' โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–‘ โ–‘โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–ˆโ–ˆโ–ˆ ', + 'โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–‘ โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ ', + 'โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–‘ โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆ ', + 'โ–‘โ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–‘ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ ', + 'โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ โ–‘โ–ˆโ–ˆโ–ˆ ', + 'โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–‘โ–‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ', + ' โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘ โ–‘โ–‘โ–‘โ–‘โ–‘ ' + ] + }, + { + lines: [ + ' _ _ _ _ _ _ _ ', + ' /\\ \\ / /\\ /\\ \\ /\\ \\ /\\ \\ / /\\ / /\\', + ' / \\ \\ / / \\ \\ \\ \\ \\_\\ \\ / \\ \\ / / / / / /', + ' / /\\ \\_\\ / / /\\ \\ /\\ \\_\\ /\\__ \\ / /\\ \\ \\ / /_/ / / / ', + ' / / /\\/_/ / / /\\ \\ \\ / /\\/_/ / /_ \\ \\ / / /\\ \\ \\ / /\\ \\__/ / / ', + ' / /_/_ / / /\\ \\_\\ \\ / / / / / /\\ \\ \\ / / / \\ \\_\\ / /\\ \\___\\/ / ', + ' / /___/\\ / / /\\ \\ \\___\\ / / / / / / \\/_// / / \\/_/ / / /\\/___/ / ', + ' / /\\__ \\ \\ / / / \\ \\ \\__/ / / / / / / / / / / / / / / / ', + ' / / /__\\ \\ \\ / / /____\\_\\ \\ ___/ / /__ / / /_ / / /________ / / / / / / ', + '/ / /____\\ \\ \\/ / /__________\\/\\__\\/_/___\\/_/ //\\_\\ / / /_________\\/ / / / / / ', + '\\/__________\\/\\/_____________/\\/_________/\\_\\/ \\/_/ \\/____________/\\/_/ \\/_/ ', + ] + }, + { + lines: [ + '_|_|_| _| _| _| _| ', + '_| _|_|_| _|_|_|_| _|_|_| _|_|_| ', + '_|_|_| _| _| _| _| _| _| _|', + '_| _| _| _| _| _| _| _| _|', + ' _|_| _|_|_| _| _|_| _| _|_|_| _| _|' + ] + }, + { + lines: [ + 'โ”Œโ”โ”Œโ” โ”ฌโ”Œโ”ฌโ”โ”Œโ”€โ”โ”ฌ โ”ฌ', + 'โ”Œโ”โ”Œโ” โ”ฌโ”Œโ”ฌโ”โ”Œโ”€โ”โ”ฌ โ”ฌ', + 'โ”œโ”โ”œโ”ดโ”โ”‚ โ”‚ โ”‚ โ”œโ”€โ”ค', + 'โ””โ”˜โ””โ”€โ”˜โ”ด โ”ดoโ””โ”€โ”˜โ”ด โ”ด', + 'โ””โ”˜โ””โ”€โ”˜โ”ด โ”ดoโ””โ”€โ”˜โ”ด โ”ด' + ] + }, + { + lines: [ + ' โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•—', + 'โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ•šโ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘', + 'โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘', + 'โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘', + 'โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•—โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ–ˆโ–ˆโ•‘', + ' โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ• โ•šโ•โ•โ•šโ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•šโ•โ• โ•šโ•โ•' + ] + }, + { + lines: [ + '00110110', + '01100010', + '01101001', + '01110100', + '00101110', + '01100011', + '01101000', + ] + }, + { + lines: [ + ' .:. :::::::. ::::::::::::: .,-::::: :: .: ', + ' ,;\' ;;;\'\'\';; ;;;\'\'\';;\'\'\' ,;;\'`````\' ,;; ;;, ', + ',[[.od8b [[[__[[\\.[[[ [[ [[[ ,[[[,,,[[[ ', + '$$$" "$$ $$""""Y$$$$$ $$ $$$ "$$$"""$$$ ', + ' Y8b,,d8P_88o,,od8P888 88 ,d8b`88bo,__,o,888 "88o', + ' "YMP" ""YUMMMP" MMM MM MYMP "YUMMMMMP MM YMM' + ] + }, + { + lines: [ + ' _.._ ', + ' .\' \'. ', + ' ( / `\\ \\ ', + ' ( |\' \' ) ) ', + ' ) _\\- / ( ', + ' __..---.(`_.\' ` \ ) ', + ' `;-""-._(_( โ™ฅ `;( ', + ' / `-`\'--\' ; ) ', + ' / / . ( โ™ฅ ,| |( ', + ' .-`\'---...__,\' /-,..___.-\'--\'_| |) ', + ' \'-\'``\'-.._ ,\' |_ / .........\' ', + ' ``;--"`; | ``` ', + ' `\'..__.\' ' + ] + }, + { + lines: [ + ' โ™ฅ ', + ' โ™ฅ โ™ฅ', + 'โ™ฅ โ™ฅ โ™ฅ โ™ฅ' + ] + }, + { + lines: [ + ' o ', + ' @ ', + ' @ ', + ' @ ', + ' o@o ', + ' o@o ', + ' o@o- o@o -o@o ', + ' o@o @@@ o@o ', + 'o@o @@@ o@o', + ' o@o @@@ o@o ', + ' o@@@@@@o @@@ o@@@@@@o ', + ' o@@@@@@@@@@@@o @@@ o@@@@@@@@@@@@o ', + ' o@@@@@@@@@@@@@@@@@o @@@ o@@@@@@@@@@@@@@@@@o ', + ' o@@@@@@@@@o @@@ o@@@@@@@@@o ', + ' o@@@o @@@ o@@@o ', + ' @@@o @@@ o@@@ ', + ' o@@@ @@@ @@@o ', + ' @@@ @@@ @@@ ', + ' o@@ @@@ @@o ', + ' @@ o@o @@ ', + ' o@ o@o @o ', + ' @ o@o @ ', + ' @ @ @ ', + ' o @ o ', + ' o ', + ' o ' + ] + }, + +]; diff --git a/html/js/hdr.js b/html/js/hdr.js new file mode 100644 index 0000000..b87546e --- /dev/null +++ b/html/js/hdr.js @@ -0,0 +1,190 @@ +(function () { + var c = document.getElementById('hdr'); + var ctx = c.getContext('2d'); + var W, H, mouse = { x: -999, y: -999 }; + var glitchX = 0, glitchY = 0; + var glitchXTarget = 0, glitchYTarget = 0; + var COLS = ['#00ffff', '#ff00ff', '#ffffff']; + /*const ARTS = [ + { + lines: [ + '' + ] + }, + ]*/ + var validARTS = ARTS.filter(function(a) { return a.lines.length > 0; }); + var ART = validARTS[Math.floor(Math.random() * validARTS.length)].lines; + + var fontSize, LINE_H, ART_TOP, PAD_BOTTOM; + + function resize() { + W = c.width = c.offsetWidth; + + var maxChars = ART.reduce(function(max, l) { return Math.max(max, l.length); }, 0); + fontSize = Math.min(16, (W * 0.95) / maxChars * 1.6); + LINE_H = fontSize * 1; + ART_TOP = LINE_H * 2; + PAD_BOTTOM = LINE_H * 2; + + H = c.height = Math.ceil(ART_TOP + ART.length * LINE_H + PAD_BOTTOM); + + buildScanlines(); + } + + var scanlines = document.createElement('canvas'); + function buildScanlines() { + var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM; + scanlines.width = 1; + scanlines.height = headerH; + var sctx = scanlines.getContext('2d'); + sctx.clearRect(0, 0, 1, headerH); + for (var sy = 0; sy < headerH; sy += 3) { + sctx.fillStyle = '#101010'; + sctx.fillRect(0, sy, 1, 1); + } + } + + window.addEventListener('resize', function () { resize(); }); + + window.addEventListener('DOMContentLoaded', function() { + resize(); + requestAnimationFrame(loop); + }); + + var moveTimer; + var glitchTarget = 0; + + var lastX = 0, lastY = 0; + document.addEventListener('mousemove', function (e) { + var nx = e.clientX; + var ny = e.clientY; + var dx = nx - lastX; + var dy = ny - lastY; + mouse.x = nx; + mouse.y = ny; + lastX = nx; + lastY = ny; + glitchXTarget = Math.min(1, Math.abs(dx) / 16); + glitchYTarget = Math.min(1, Math.abs(dy) / 16); + clearTimeout(moveTimer); + moveTimer = setTimeout(function () { glitchXTarget = 0; glitchYTarget = 0; }, 100); + }); + + document.addEventListener('mouseleave', function () { + mouse.x = -999; + glitchXTarget = 0; + glitchYTarget = 0; + }); + + document.addEventListener('touchmove', function (e) { + var touch = e.touches[0]; + var nx = touch.clientX; + var ny = touch.clientY; + var dx = nx - lastX; + var dy = ny - lastY; + mouse.x = nx; + mouse.y = ny; + lastX = nx; + lastY = ny; + glitchXTarget = Math.min(1, Math.abs(dx) / 16); + glitchYTarget = Math.min(1, Math.abs(dy) / 16); + clearTimeout(moveTimer); + moveTimer = setTimeout(function () { glitchXTarget = 0; glitchYTarget = 0; }, 100); + }, { passive: true }); + + document.addEventListener('touchend', function () { + glitchXTarget = 0; + glitchYTarget = 0; + }); + + /* โ”€โ”€ text โ”€โ”€ */ + function drawText(ox, oy, col, alpha) { + ctx.save(); + ctx.globalAlpha = alpha; + ctx.fillStyle = col; + ctx.font = fontSize + 'px deltarune'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + for (var i = 0; i < ART.length; i++) { + ctx.fillText(ART[i], W / 2 + ox, ART_TOP + i * LINE_H + oy, W * 0.95); + } + ctx.restore(); + } + + /* โ”€โ”€ proximity glow on letters โ”€โ”€ */ + function drawGlow() { + var cx = W / 2; + var cy = ART_TOP + (ART.length * LINE_H) / 2; + var dx = mouse.x - cx; + var dy = mouse.y - cy; + var dist = Math.sqrt(dx * dx + dy * dy); + var r = Math.max(0, 1 - dist / 220); + var idle = (1 - r) * (Math.sin(t * 0.008) * 0.5 + 0.5) * 0.25; + + if (idle > 0) { + ctx.save(); + ctx.globalAlpha = idle * 0.15; + ctx.fillStyle = '#00ffff'; + ctx.font = fontSize + 'px deltarune'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + for (var d = 3; d <= 9; d += 3) { + for (var i = 0; i < ART.length; i++) { + ctx.fillText(ART[i], W / 2 + d, ART_TOP + i * LINE_H, W * 0.95); + ctx.fillText(ART[i], W / 2 - d, ART_TOP + i * LINE_H, W * 0.95); + ctx.fillText(ART[i], W / 2, ART_TOP + i * LINE_H + d, W * 0.95); + ctx.fillText(ART[i], W / 2, ART_TOP + i * LINE_H - d, W * 0.95); + } + } + ctx.restore(); + } + + if (r <= 0) return; + ctx.save(); + ctx.globalAlpha = r * 0.3; + ctx.fillStyle = '#ff00ff'; + ctx.font = fontSize + 'px deltarune'; + ctx.textAlign = 'center'; + ctx.textBaseline = 'top'; + for (var d = 3; d <= 9; d += 3) { + for (var i = 0; i < ART.length; i++) { + ctx.fillText(ART[i], W / 2 + d, ART_TOP + i * LINE_H, W * 0.95); + ctx.fillText(ART[i], W / 2 - d, ART_TOP + i * LINE_H, W * 0.95); + } + } + ctx.restore(); + } + + /* โ”€โ”€ main loop โ”€โ”€ */ + var t = 0, lastFrame = 0; + function loop(ts) { + requestAnimationFrame(loop); + if (ts - lastFrame < 42) return; + lastFrame = ts; + t++; + + ctx.clearRect(0, 0, W, H); + var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM; + + var splitX = glitchX * 16; + var splitY = glitchY * 16; + + drawText(-splitX, -splitY, '#00ffff', 0.7); + drawText( splitX, splitY, '#ff00ff', 0.7); + drawText(0, 0, '#ffffff', 0.9); + + drawGlow(); + + /* scanline overlay */ + var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM; + ctx.drawImage(scanlines, 0, 0, W, headerH); + + glitchX += (glitchXTarget - glitchX) * 0.04; + glitchY += (glitchYTarget - glitchY) * 0.04; + } + + window.rerollArt = function() { + ART = validARTS[Math.floor(Math.random() * validARTS.length)].lines; + resize(); + }; +})(); diff --git a/html/js/hearts.js b/html/js/hearts.js new file mode 100755 index 0000000..2624070 --- /dev/null +++ b/html/js/hearts.js @@ -0,0 +1,178 @@ +//var colours=new Array('#f00', '#f06', '#f0f', '#f6f', '#f39', '#f9c'); // colours of the hearts +var colours=new Array('#ff00ff','#00ffff'); // colours of the hearts +var minisize=10; // smallest size of hearts in pixels +var maxisize=20; // biggest size of hearts in pixels +var hearts=100; // maximum number of hearts on screen +var over_or_under="over"; // set to "over" for hearts to always be on top, or "under" to allow them to float behind other objects + +/* Thanks mf2fm.com for this + * + */ + +/***************************** +*JavaScript Love Heart Cursor* +* (c)2013+ mf2fm web-design * +* http://www.mf2fm.com/rv * +* DON'T EDIT BELOW THIS BOX * +*****************************/ +var x=ox=400; +var y=oy=300; +var swide=800; +var shigh=600; +var sleft=sdown=0; +var herz=new Array(); +var herzx=new Array(); +var herzy=new Array(); +var herzs=new Array(); +var kiss=true; + +if (typeof('addRVLoadEvent')!='function') function addRVLoadEvent(funky) { + var oldonload=window.onload; + if (typeof(oldonload)!='function') window.onload=funky; + else window.onload=function() { + if (oldonload) oldonload(); + funky(); + } +} + +addRVLoadEvent(mwah); + +function mwah() { if (document.getElementById) { + var i, heart; + for (i=0; i1 || Math.abs(y-oy)>1) { + ox=x; + oy=y; + for (c=0; csleft+swide-herzs[i]) { + herz[i].style.visibility="hidden"; + herzy[i]=false; + } + else if (herzs[i]>minisize+1 && Math.random()<2.5/hearts) break_my_heart(i); + else { + if (Math.random()0) sw_min=document.documentElement.clientWidth; + if (document.documentElement.clientHeight>0) sh_min=document.documentElement.clientHeight; + } + if (typeof(self.innerWidth)=='number' && self.innerWidth) { + if (self.innerWidth>0 && self.innerWidth0 && self.innerHeight0 && document.body.clientWidth0 && document.body.clientHeightanarki' + }; + + function colorizeSpectator(name) { + return colorizedNames[name.toLowerCase()] || name; + } + + function buildDoc(cfg) { + var redRows = cfg.redTeam .map(function(p){ return '
0 ' + p + '
'; }).join(''); + var blueRows = cfg.blueTeam.map(function(p){ return '
0 ' + p + '
'; }).join(''); + var label = cfg.serverLabel.split(' '); + var bracket = label[0] || ''; + var cyan = label[1] || ''; + var yellow = label.slice(2).join(' ') || ''; + + var css = [ + '*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}', + 'html,body{background:transparent;color:#ccc;font-family:"Courier New",Courier,monospace;font-size:12.5px;line-height:1.5;overflow:hidden}', + '.wrap{border:1px solid #333}', + '.header{padding:6px 12px 4px}', + '.titlebar{color:#ccc;margin-bottom:6px}', + '.infoline{display:grid;grid-template-columns:auto auto auto auto;margin-bottom:1px}', + '.teams{padding:8px 12px 4px;display:flex}', + '.team{width:50%}', + '.team-hdr{margin-bottom:3px}', + '.player{color:#fff;padding-left:2px}', + '.spectators{padding:4px 12px 2px;color:#ff0;font-weight:bold}', + '.divider{border:none;border-top:1px solid #444;margin:6px 0 0;display:block}', + '.feed-wrap{height:256px;overflow:hidden;padding:4px 12px;position:relative}', + '.fade{position:absolute;top:4px;left:0;right:0;height:30px;background:linear-gradient(to bottom,#0c0c0c,transparent);pointer-events:none;z-index:2}', + '.feed{display:flex;flex-direction:column}', + '.msg{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;opacity:0;transition:opacity .25s ease;line-height:1.6;display:block}', + '.msg.on{opacity:1}', + '.cmdline{border-top:1px solid #333;padding:4px 12px;display:flex;align-items:center;gap:4px;color:#ccc}', + '.cursor{display:inline-block;width:8px;height:14px;background:#ccc;vertical-align:middle;animation:blink 1s step-end infinite}', + '@keyframes blink{0%,100%{opacity:1}50%{opacity:0}}', + '.cyan{color:#fff}.yellow{color:#0cc}.warmup{color:#f00}', + '.bold{color:#fff;font-weight:bold}', + '.rt{color:#f00;text-decoration:underline;font-weight:bold}', + '.bt{color:#09f;text-decoration:underline;font-weight:bold}', + '.score{color:#fff;font-weight:bold;margin-right:6px}', + '.ts{color:#ccc}.cr{color:#f00}.cb{color:#09f}.cp{color:#fff;font-weight:bold}', + '.cmt{color:#f0f;font-weight:bold}', + '.cst{color:#0c0;font-weight:bold}.css{color:#0f0}', + '.plain{color:#ccc}', + '.label{color:#ff0}', + ].join(''); + + var html = [ + '', + '', + '', + '
', + '
', + '
Quake Live PyCon: ', cfg.host, '
', + '
', + 'Name: [+] ', cyan, ' ', yellow, '', + '', + 'Time: 0:00', + 'Warmup: YES', + '
', + '
', + 'Type: ', cfg.gameType, '', + 'Map: ', cfg.mapName, '', + 'Players: ', cfg.playerSlots, '', + 'Roundlimit: ', cfg.roundLimit, '', + '
', + '
', + '
', + '
', + '
0RED TEAM
', + redRows, + '
', + '
', + '
0BLUE TEAM
', + blueRows, + '
', + '
', + '
Spectators: ' + cfg.spectators.map(colorizeSpectator).join(' ') + '
', + '
', + '
', + '
', + '
', + '
', + '
$
', + '
', + ].join(''); + + /* inner script as a real function โ€” no string escaping needed */ + function iframeScript(cfg) { + var feed = document.getElementById('feed'); + var timeEl = document.getElementById('qtime'); + var rsEl = document.getElementById('rs'); + var bsEl = document.getElementById('bs'); + var lines = [], elapsed = 0, scores = { red: 0, blue: 0 }; + + function rand(a) { return a[Math.floor(Math.random() * a.length)]; } + function randInt(a,b){ return a + Math.floor(Math.random() * (b - a + 1)); } + function sp(c, t) { return '' + t + ''; } + function pad(n) { return n < 10 ? '0' + n : '' + n; } + function ts() { + var b = 33*60 + 34 + elapsed; + return '[' + pad(Math.floor(b/3600)) + ':' + pad(Math.floor((b%3600)/60)) + ':' + pad(b%60) + ']'; + } + + function kill() { + var rk = Math.random() < 0.5; + var k = rand(rk ? cfg.redTeam : cfg.blueTeam); + var v = rand(rk ? cfg.blueTeam : cfg.redTeam); + var w = rand(cfg.weapons); + var hp = randInt(25, 200); + if (Math.random() < 0.12) { if (rk) scores.red++; else scores.blue++; } + return sp('ts',ts()) + ' ' + + sp(rk?'cr':'cb', rk?'(RED)':'(BLUE)') + sp('cp', k) + + sp('plain', ' fragged ') + + sp(rk?'cb':'cr', rk?'(BLUE)':'(RED)') + sp('cp', v) + + sp('plain', ' with the ') + + (function(w){ + var weaponColors = { + 'Rocket Launcher':'#f33', + 'Plasma Gun':'#f0f', + 'Railgun':'#0f0', + 'Lightning Gun':'#ff0', + 'Shotgun':'#f60' + }; + return '' + w + ''; + })(w) + ' ' + + sp('chp', '(' + hp + ' HP)'); + } + + function medal() { + var r = Math.random() < 0.5; + return sp('ts',ts()) + ' ' + + sp('cmt', '[MEDAL]') + ' ' + + sp(r?'cr':'cb', r?'(RED)':'(BLUE)') + + sp('cp', rand(r ? cfg.redTeam : cfg.blueTeam)) + + sp('plain', ' got ') + + (function(m){ + var medalColors = { + 'EXCELLENT':'#ff0', + 'MIDAIR':'#0f0', + 'IMPRESSIVE':'#0cc', + 'REVENGE':'#f00' + }; + return '' + m + ''; + })(rand(cfg.medals)); + } + + function say() { + var r = Math.random() < 0.5; + return sp('ts',ts()) + ' ' + + sp('cst', '[SAY]') + ' ' + + sp(r?'cr':'cb', r?'(RED)':'(BLUE)') + + sp('cp', rand(r ? cfg.redTeam : cfg.blueTeam)) + + ': ' + sp('css', rand(cfg.chatMessages)); + } + + function addLine(h) { + var d = document.createElement('div'); + d.className = 'msg'; + d.innerHTML = h; + feed.appendChild(d); + lines.push(d); + requestAnimationFrame(function(){ d.classList.add('on'); }); + if (lines.length > cfg.maxLines) lines.shift().remove(); + rsEl.textContent = scores.red; + bsEl.textContent = scores.blue; + } + + function schedule() { + setTimeout(function() { + var r = Math.random(); + if (r < cfg.pKill) addLine(kill()); + else if (r < cfg.pKill + cfg.pMedal) addLine(medal()); + else addLine(say()); + schedule(); + }, randInt(cfg.minDelay, cfg.maxDelay)); + } + + addLine(sp('plain', '*** ')); + addLine(sp('plain', '*** QL PyCon Version 0.8.1 starting ***')); + addLine(sp('plain', 'Stats stream connected - ready for game events')); + + setInterval(function() { + elapsed++; + var m = Math.floor(elapsed / 60), s = elapsed % 60; + timeEl.textContent = m + ':' + (s < 10 ? '0' : '') + s; + }, 1000); + + setTimeout(schedule, 900); + } + + var scriptBody = '(' + iframeScript.toString() + ')(' + JSON.stringify(cfg) + ')'; + + return html + '' + scriptBody + ''; + } + + var instanceCount = 0; + + function mount(root, cfg) { + var iframe = document.createElement('iframe'); + iframe.style.cssText = 'width:100%;height:100%;border:none;display:block;'; + iframe.setAttribute('scrolling', 'no'); + iframe.setAttribute('title', 'Quake Live terminal'); + root.appendChild(iframe); + var doc = iframe.contentDocument || iframe.contentWindow.document; + doc.open(); + doc.write(buildDoc(cfg)); + doc.close(); + } + + global.QuakeTerminal = { + init: function(selector, userConfig) { + var root = typeof selector === 'string' + ? document.querySelector(selector) + : selector; + if (!root) { console.warn('QuakeTerminal: element not found โ€”', selector); return; } + + var cfg = {}; + for (var k in DEFAULTS) cfg[k] = DEFAULTS[k]; + for (var k in (userConfig || {})) cfg[k] = userConfig[k]; + cfg._id = ++instanceCount; + + var details = root.closest('details'); + if (details && !details.open) { + details.addEventListener('toggle', function onToggle() { + if (details.open) { + details.removeEventListener('toggle', onToggle); + mount(root, cfg); + } + }); + } else { + mount(root, cfg); + } + }, + defaults: DEFAULTS, + }; + +}(window)); diff --git a/html/js/qlpyconbanner.js b/html/js/qlpyconbanner.js new file mode 100644 index 0000000..a812f4f --- /dev/null +++ b/html/js/qlpyconbanner.js @@ -0,0 +1,35 @@ +const text = ` + _/ + _/_/_/ _/ _/_/_/ _/ _/ _/_/_/ _/_/ _/_/_/ + _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ +_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ + _/_/_/ _/ _/_/_/ _/_/_/ _/_/_/ _/_/ _/ _/ + _/ _/ _/ + _/ _/ _/_/ +`; + +function lerp(a, b, t) { + return a + (b - a) * t; +} + +function color(t) { + const c1 = [0, 255, 255]; // cyan + const c2 = [255, 0, 255]; // magenta + const r = Math.round(lerp(c1[0], c2[0], t)); + const g = Math.round(lerp(c1[1], c2[1], t)); + const b = Math.round(lerp(c1[2], c2[2], t)); + return `rgb(${r},${g},${b})`; +} + +let out = ""; +const lines = text.split("\n"); + +lines.forEach(line => { + for (let i = 0; i < line.length; i++) { + const t = i / Math.max(line.length - 1, 1); + out += `${line[i] || " "}`; + } + out += "
"; +}); + +document.getElementById("qlpyconbanner").innerHTML = out; diff --git a/html/js/snek.js b/html/js/snek.js new file mode 100644 index 0000000..d829d30 --- /dev/null +++ b/html/js/snek.js @@ -0,0 +1,158 @@ +var snekStarted = false; +document.querySelector('#snek-details').addEventListener('toggle', function(e) { + if (e.target.open && !snekStarted) { + snekStarted = true; + +var canvas = document.getElementById('game'); +var context = canvas.getContext('2d'); + +var grid = 8; +var count = 8; + +var snake = { + x: 160, + y: 160, + + // snake velocity. moves one grid length every frame in either the x or y direction + dx: grid, + dy: 0, + + // keep track of all grids the snake body occupies + cells: [], + + // length of the snake. grows when eating an apple + maxCells: 4 +}; + +var cols = Math.floor(canvas.width / grid); +var rows = Math.floor(canvas.height / grid); +var apple = { + x: getRandomInt(0, cols) * grid, + y: getRandomInt(0, rows) * grid, +}; + +// get random whole numbers in a specific range +// @see https://stackoverflow.com/a/1527820/2124254 +function getRandomInt(min, max) { + return Math.floor(Math.random() * (max - min)) + min; +} + +// game loop +function loop() { + requestAnimationFrame(loop); + + // slow game loop to 15 fps instead of 60 (60/15 = 4) + if (++count < 11) { + return; + } + + count = 0; + context.clearRect(0,0,canvas.width,canvas.height); + + context.font = '9px sans-serif'; + context.fillStyle = '#696969'; + context.fillText(snake.maxCells, canvas.width - 20, 14); + + // move snake by it's velocity + snake.x += snake.dx; + snake.y += snake.dy; + + // wrap snake position + if (snake.x < 0) { + snake.x = (cols - 1) * grid; + } + else if (snake.x >= canvas.width) { + snake.x = 0; + } + if (snake.y < 0) { + snake.y = (rows - 1) * grid; + } + else if (snake.y >= canvas.height) { + snake.y = 0; + } + + // keep track of where snake has been. front of the array is always the head + snake.cells.unshift({x: snake.x, y: snake.y}); + + // remove cells as we move away from them + if (snake.cells.length > snake.maxCells) { + snake.cells.pop(); + } + + // draw apple + context.fillStyle = 'cyan'; + context.fillRect(apple.x, apple.y, grid-1, grid-1); + + // draw snake one cell at a time + context.fillStyle = 'magenta'; + snake.cells.forEach(function(cell, index) { + + // drawing 1 px smaller than the grid creates a grid effect in the snake body so you can see how long it is + context.fillRect(cell.x, cell.y, grid-1, grid-1); + + // snake ate apple + if (cell.x === apple.x && cell.y === apple.y) { + snake.maxCells++; + + // canvas is 400x400 which is 25x25 grids + apple.x = getRandomInt(0, cols) * grid; + apple.y = getRandomInt(0, rows) * grid; + } + + // check collision with all cells after this one (modified bubble sort) + for (var i = index + 1; i < snake.cells.length; i++) { + + // snake occupies same space as a body part. reset game + if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) { + snake.x = 160; + snake.y = 160; + snake.cells = []; + snake.maxCells = 4; + snake.dx = grid; + snake.dy = 0; + + apple.x = getRandomInt(0, 25) * grid; + apple.y = getRandomInt(0, 25) * grid; + } + } + }); +} + +// listen to keyboard events to move the snake +document.addEventListener('keydown', function(e) { + if (document.getElementById('snek-details').open) { + if ([37, 38, 39, 40].indexOf(e.which) !== -1) { + e.preventDefault(); + } + } + // prevent snake from backtracking on itself by checking that it's + // not already moving on the same axis (pressing left while moving + // left won't do anything, and pressing right while moving left + // shouldn't let you collide with your own body) + + // left arrow key + if (e.which === 37 && snake.dx === 0) { + snake.dx = -grid; + snake.dy = 0; + } + // up arrow key + else if (e.which === 38 && snake.dy === 0) { + snake.dy = -grid; + snake.dx = 0; + } + // right arrow key + else if (e.which === 39 && snake.dx === 0) { + snake.dx = grid; + snake.dy = 0; + } + // down arrow key + else if (e.which === 40 && snake.dy === 0) { + snake.dy = grid; + snake.dx = 0; + } +}); + +// start the game +requestAnimationFrame(loop); +} +}); diff --git a/html/js/sparks.js b/html/js/sparks.js new file mode 100644 index 0000000..16f7d15 --- /dev/null +++ b/html/js/sparks.js @@ -0,0 +1,28 @@ +$(function() { + var body = $('#starshine'), + template = $('.template.shine'), + stars = 500, + sparkle = 50; + + var size = 'small'; + var createStar = function() { + template.clone().removeAttr('id').css({ + top: (Math.random() * 100) + '%', + left: (Math.random() * 100) + '%', + webkitAnimationDelay: (Math.random() * sparkle) + 's', + mozAnimationDelay: (Math.random() * sparkle) + 's' + }).addClass(size).appendTo(body); + }; + + for(var i = 0; i < stars; i++) { + if(i % 2 === 0) { + size = 'small'; + } else if(i % 3 === 0) { + size = 'medium'; + } else { + size = 'large'; + } + + createStar(); + } +}); diff --git a/html/js/stars.js b/html/js/stars.js new file mode 100644 index 0000000..4efe86d --- /dev/null +++ b/html/js/stars.js @@ -0,0 +1,85 @@ +/* stars.js โ€” static starry background for 6bit.ch + Requires a in your HTML: + position: fixed; inset: 0; width: 100%; height: 100%; + z-index: -2; pointer-events: none; */ + +(function () { + const canvas = document.getElementById('stars'); + if (!canvas) return; + const ctx = canvas.getContext('2d'); + + /* โ”€โ”€ CONFIG โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ + const CONFIG = { + count: 280, + colorVariation: 1.0, // 0 = pure white, 1 = full spectral color + bgColor: '#101010', + }; + + /* โ”€โ”€ PALETTE (stellar spectral classes) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ + const PALETTE = [ + [160, 190, 255], // deep blue (O/B) + [200, 220, 255], // blue-white (A) + [255, 244, 180], // yellow (F/G) + [255, 210, 140], // orange (K) + [255, 160, 120], // red-orange (M) + [140, 220, 255], // cyan-blue + [255, 230, 255], // violet-white + ]; + + function randColor() { + const base = PALETTE[Math.floor(Math.random() * PALETTE.length)]; + const m = CONFIG.colorVariation; + return base.map(c => Math.round(255 * (1 - m) + c * m)); + } + + let W, H; + + function resize() { + W = canvas.width = window.innerWidth; + H = canvas.height = window.innerHeight; + draw(); + } + + function draw() { + if (CONFIG.bgColor) { + ctx.fillStyle = CONFIG.bgColor; + ctx.fillRect(0, 0, W, H); + } else { + ctx.clearRect(0, 0, W, H); + } + + for (let i = 0; i < CONFIG.count; i++) { + const r = Math.random(); + const size = r < 0.65 + ? 0.45 + Math.random() * 0.30 + : r < 0.90 + ? 0.85 + Math.random() * 0.30 + : 1.40 + Math.random() * 0.40; + + const x = Math.random() * W; + const y = Math.random() * H; + const alpha = 0.35 + Math.random() * 0.65; + const [cr, cg, cb] = randColor(); + + /* soft halo on brighter stars */ + if (size > 1.0) { + const halo = ctx.createRadialGradient(x, y, 0, x, y, size * 2.5); + halo.addColorStop(0, `rgba(${cr},${cg},${cb},${(alpha * 0.45).toFixed(3)})`); + halo.addColorStop(1, `rgba(${cr},${cg},${cb},0)`); + ctx.beginPath(); + ctx.arc(x, y, size * 2.5, 0, Math.PI * 2); + ctx.fillStyle = halo; + ctx.fill(); + } + + /* star core */ + ctx.beginPath(); + ctx.arc(x, y, size, 0, Math.PI * 2); + ctx.fillStyle = `rgba(${cr},${cg},${cb},${alpha.toFixed(3)})`; + ctx.fill(); + } + } + + resize(); + window.addEventListener('resize', resize); +})(); diff --git a/html/slamp.html b/html/slamp.html index 6ebb507..b1510ab 100644 --- a/html/slamp.html +++ b/html/slamp.html @@ -43,6 +43,14 @@ var color = document.getElementById("body"); color.style.backgroundColor = "#042069"; } + function changeColor1312() { + var color = document.getElementById("body"); + color.style.backgroundColor = "#F1312F"; + } + function changeColor161() { + var color = document.getElementById("body"); + color.style.backgroundColor = "#FFF161"; + } @@ -60,6 +68,8 @@ + +


diff --git a/html/style.css b/html/style.css index 03e4a52..d69ca9f 100644 --- a/html/style.css +++ b/html/style.css @@ -1,81 +1,68 @@ * { margin: 0; padding: 0; - font-family: "FiraSans", sans-serif; + font-family: "deltarune", monospace; + box-sizing: border-box; } body { + background-color: #101010; padding: 0; margin:0; - background-color: #101010 + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + -webkit-user-select: none; /* Chrome, Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* old IE/Edge */ + user-select: none; /* standard */ } -div {box-sizing: border-box;} +#hdr { + position: block; + top: 0; + left: 0; + width: 100%; + z-index: 999; + pointer-events: none; +} -#starshine { - position: absolute; +#stars { + position: fixed; + inset: 0; + width: 100%; + height: 100%; + z-index: -2; + pointer-events: none; +} + +#particles { + position: fixed; top: 0; left: 0; width: 100%; height: 100%; - z-index: -5; - overflow: hidden; -} - -.shine { - display: block; - position: absolute; - top: 50%; - left: 50%; - background-image: url(https://6bit.ch/spark.png); - background-repeat: no-repeat; - background-position:center; - background-size: 100% 100%; - overflow: hidden; - z-index: 2; - color: transparent; - -moz-opacity: 0.0; - opacity: 0.0; - animation: glitter 6s linear 0s infinite normal; - -webkit-animation: glitter 6s linear 0s infinite normal; - -moz-animation: glitter 8s linear 0s infinite normal; - -ms-animation: glitter 8s linear 0s infinite normal; - -o-animation: glitter 8s linear 0s infinite normal; + pointer-events: none; + z-index: 0; } -.shine.small { - width: 1px; - height: 1px; +h1, h2, h3, h4, p { + color: #F0F0F0; } -.shine.medium { - width: 3px; - height: 3px; +.reroll-btn { + background: none; + border: none; + color: magenta; + font-size: 13px; + cursor: pointer; + opacity: 0.6; + padding: 4px 0; } -.shine.large { - width: 5px; - height: 5px; -} - -/*CSS3 keyframes for glittering effect*/ -@-webkit-keyframes glitter { - 0% { - -webkit-transform: scale(0.3) rotate(0deg); - opacity: 0; - } - 25% { - -webkit-transform: scale(1) rotate(360deg); - opacity: 1; - } - 50% { - -webkit-transform: scale(0.3) rotate(720deg); - opacity: 0; - } - 100% { - -webkit-transform: scale(0.3) rotate(0deg); - opacity: 0; - } +.reroll-btn:hover { + opacity: 1; } .snake-box { @@ -84,7 +71,6 @@ div {box-sizing: border-box;} top: 0px; text-align: center; margin-bottom: 1%; - z-index: 500; text-align: center; margin-bottom: 1%; border: 1px cyan dotted; @@ -92,11 +78,10 @@ div {box-sizing: border-box;} .footer { width: 100%; - color: #101010; - position: relative; + flex-shrink: 0; text-align: center; - padding-top: 3%; - background-color: #101010; + padding: 15px; + margin-top: auto; } .footer p { @@ -122,18 +107,16 @@ div {box-sizing: border-box;} } .main { + max-width: 720px; width: 100%; - height: auto; -} - -.main:after { - content:""; - display: table; - clear: both; + display: flex; + flex-direction: column; + gap: 1.5rem; + padding-top: 1.5rem; + flex-grow: 1; } .col { - position: relative; color: white; } @@ -150,78 +133,24 @@ div {box-sizing: border-box;} } -.left { - width: 15%; - float: left; - left: 3%; -} - -.left h4 { - text-decoration: none; - padding-right: 50px; - padding-left: 5px; - padding-bottom: 2px; - margin-right: 0px; - margin-left: 0px; - margin-bottom: 3px; - color: #101010; - background: rgb(0,255,255); - background: linear-gradient(90deg, rgba(255,0,255,1) 0%, rgba(10,10,10,0) 100%); - font-size: 17px; - font-weight: 500; -} - -.left ul { - display: flex; - width: auto; - padding: 5px; - color: #FFFFFF; - text-decoration: none; - padding-left: 15px; - font-size: 15px; - list-style-type: none; -} - -.left li { - width: 100%; - text-decoration: none; -} - -.left a { - color: #FFFFFF; - text-decoration: none; - display: block; - padding-top: 2px; - padding-bottom: 2px; - padding-left: 5px; -} - -.left a:hover { - background: linear-gradient(90deg, rgba(255,0,255,0.2) 0%, rgba(10,10,10,0) 100%); -} - -.right { - position: relative; - width: 69%; - float: left; - left: 7%; +.col-full { + grid-column: 1 / -1; } .contentindex { padding: 3%; width: 100%; - z-index: 2200; text-align: left; border: 1px; border-style: dotted; border-color: cyan; text-align: center; + background-color: rgba(16, 16, 16, 0.69); } .contentindexart { padding: 3%; width: 100%; - z-index: 2200; text-align: left; border: 1px; border-style: dotted; @@ -230,6 +159,69 @@ div {box-sizing: border-box;} display: flex; flex-wrap: wrap; gap: 50px; + justify-content: center; +} + +.contentindexqlpycon { + padding: 3%; + width: 100%; + border: 1px; + border-style: dotted; + border-color: cyan; + text-align: center; +} + +.contentindexqlpycon pre { + font-size: 15px; +} + +.contentindexqlpycon h1 { + padding: 1.25rem 0; +} + +.contentindexqlpycon h2 { + padding: 1rem 0; +} + +.contentindexqlpycon h3 { + padding: 1rem 0; +} + +.contentindexqlpycon h4 { + text-align: left; + padding-top: 1rem; +} + +.contentindexqlpycon p { + text-align: left; +} + +.contentindexqlpycon a { + color: white; + text-decoration: none; + border-bottom: 1px dotted magenta; +} + +.qlpyconcodeblock { + font-size: 14px; + border: 1px dotted #ff00ff; + margin: 1rem; + padding: 1rem 0.5rem; +} + +.qlpyconcode { + padding: 2px 16px; + color: cyan; + font-size: 14px; + user-select: text; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; +} + +#qlpycon { + max-width: 672px; + height: 500px; } .contentindex img { @@ -242,9 +234,8 @@ div {box-sizing: border-box;} } .contentindex p { - margin-top: 5px; - margin-bottom: 5px; - padding-bottom: 25px; + margin-top: 0px; + margin-bottom: 0px; } .contentindex a { @@ -291,100 +282,138 @@ div {box-sizing: border-box;} } } -#@-webkit-keyframes glow { -# from { -# text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #e60073, 0 0 40px #e60073, 0 0 50px #e60073, 0 0 60px #e60073, 0 0 70px #e60073; -# } -# -# to { -# text-shadow: 0 0 20px #fff, 0 0 30px #ff4da6, 0 0 40px #ff4da6, 0 0 50px #ff4da6, 0 0 60px #ff4da6, 0 0 70px #ff4da6, 0 0 80px #ff4da6; -# } -#} +.headerimg { + text-align: center; +} + +.headerimg img { + height: 80px; + width: auto; + margin: 0 auto; +} + +.linksblock { + display: grid; + gap: 1.5rem; + border: 1px dotted magenta; + padding: 1rem 1.25rem; + justify-content: center; + grid-template-columns: 1fr 1fr; + background-color: rgba(16, 16, 16, 0.69); +} + +.linkgroup { + flex: 1; +} + +.linkgroup-everywhere { + grid-column: 1 / -1; +} + +.linkgroup-everywhere ul { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 0 1.5rem; + justify-content: center; +} + +.linkgroup h4 { + color: #101010; + background: linear-gradient(90deg, rgba(255,0,255,1) 0%, rgba(10,10,10,0) 100%); + font-size: 14px; + font-weight: 500; + padding: 2px 4px; + margin-bottom: 4px; +} + +.linkgroup ul { + list-style: none; + padding: 0; +} + +.linkgroup a { + color: #ffffff; + text-decoration: none; + font-size: 14px; + display: block; + padding: 2px 5px; +} + +.linkgroup a:hover { + color: magenta; +} + +.things-block { + border: 1px dotted magenta; + background-color: rgba(16, 16, 16, 0.69); +} + +.things-block summary { + cursor: pointer; + padding: 4px 4px; + font-size: 14px; + font-weight: 500; + color: #101010; + background: linear-gradient(90deg, rgba(255,0,255,1) 0%, rgba(10,10,10,0) 100%); + list-style: none; + user-select: none; + display: flex; + justify-content: space-between; + align-items: center; +} + +.things-block summary::-webkit-details-marker { + display: none; +} + +.things-block summary:hover { + background: linear-gradient(90deg, rgba(255,0,255,0.8) 0%, rgba(10,10,10,0) 100%); +} + +.things-block summary::after { + content: 'โ–ผ'; + display: inline-block; + margin-right: 6px; + color: white; + transition: transform .2s; +} + +.things-block[open] summary::after { + transform: rotate(180deg); +} + +.things-block[open] summary { + margin-bottom: 1rem; +} + +#game { + display: block; + width: 100%; + border: 1px dotted cyan; + background-color: rgba(16, 16, 16, 0.69); +} @font-face { - font-family: FiraSans; - src: url("fonts/FiraSans-Medium.otf") format: ("opentype"); + font-family: "FiraSans"; + font-display: swap; + src: url("fonts/FiraSans-Regular.otf") format("opentype"); } -@media(max-width: 1350px) { +@font-face { + font-family: "deltarune"; + src: url("fonts/inconreg.ttf") format('truetype'); + font-display: swap; +} + +@media (max-width: 480px) { .main { - overflow: hidden; - padding: 0; - margin: 0; + gap: 1rem; } - .headerimg { - width 248px; - margin-left: 5%; - margin-right: 5%; - } - .headerimg img { - display: block; - position: center; - margin: 0; - padding-top: 33px; - padding-bottom: 33px; - width: auto; - height: auto; - max-height: 69px; - margin: auto; - } - .col { - overflow: hidden; - width: 100%; - left: 0; - right: 0; - } - .left { - overflow: hidden; - width: 100%; - } - .navblock h4 { - font-size: 14px; - } - .navblock ul { - font-size: 14px; - } - .right { - overflow: hidden; - margin-top: 100px; - border: 1px cyan dotted; - width: 100%; - overflow: hidden; - } - .contentindex { - overflow: hidden; - border: none; - padding: 0; - margin: 0; - } - .contentindexart { - overflow: hidden; - border: none; - margin: 0; - padding: 0; - display: block; - justify-content: center; - } - .artitem { - padding-top: 25px; - padding-bottom: 25px; + .linksblock { + gap: 1rem; } .artitem img { - padding: 0; - height: auto; - width: 69%; - } - .right p { - margin: auto; - font-size: 12px; - } - .footer { - margin-top: 100px; - } - .footer a { - font-size: 11px; - } - .footer p { - font-size: 11px; + height: 100px; } }