From 03da81a84cb4198b4378a46dda2c305fa4fe5f6a Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sat, 30 Apr 2022 11:10:09 +0300 Subject: [PATCH] New navigation (#821) * Menu skeleton * Menu with nav icons * Menu opens and closes * More menu icons + links work * Menu closes on navigation * Blurred menu * Remove other nav * Rounded nav * Fix menu alignment for Safari * Close on click outside * Disable body scroll when menu open * SubNav for tournament * Use grid * Make images same size again * Remove comment * Different style mobile nav * Readd InfoBanner elements * Move menu css to layout.css * Move admin command input top left * Page title from loader * Fix error when getting pageTitle * Fix CI --- app/components/Catcher.tsx | 4 +- app/components/Layout/DrawingSection.tsx | 373 ++++++++++++++++++ app/components/Layout/Menu.tsx | 70 ++++ .../Layout/{MobileNav.tsx => MobileMenu.tsx} | 9 +- app/components/Layout/SearchInput.tsx | 6 +- app/components/Layout/index.tsx | 107 +++-- app/components/SubNav.tsx | 24 ++ app/components/icons/ArrowUp.tsx | 2 +- app/components/icons/GitHub.tsx | 15 + app/components/icons/Patreon.tsx | 16 + app/components/tournament/InfoBanner.tsx | 63 +-- app/constants.ts | 8 +- app/hooks/common.ts | 30 ++ app/root.tsx | 69 ++-- app/routes/beta.tsx | 32 -- app/routes/play/match.$id.tsx | 12 +- app/routes/to/$organization.$tournament.tsx | 147 ++++--- .../to/$organization.$tournament/index.tsx | 8 +- app/styles/global.css | 40 +- app/styles/layout.css | 302 ++++++++------ app/styles/tournament-match.css | 2 +- app/styles/tournament.css | 79 ---- app/utils/index.ts | 29 +- app/utils/urls.ts | 9 + package-lock.json | 37 +- package.json | 2 + .../img/layout/{browse.webp => builds.webp} | Bin public/img/layout/new_boy_bg.png | Bin 0 -> 36391 bytes public/img/layout/new_boy_dark.png | Bin 0 -> 783956 bytes public/img/layout/new_girl_bg.png | Bin 0 -> 38362 bytes public/img/layout/new_girl_dark.png | Bin 0 -> 650128 bytes window.d.ts | 7 - 32 files changed, 995 insertions(+), 507 deletions(-) create mode 100644 app/components/Layout/DrawingSection.tsx create mode 100644 app/components/Layout/Menu.tsx rename app/components/Layout/{MobileNav.tsx => MobileMenu.tsx} (89%) create mode 100644 app/components/SubNav.tsx create mode 100644 app/components/icons/GitHub.tsx create mode 100644 app/components/icons/Patreon.tsx delete mode 100644 app/routes/beta.tsx rename public/img/layout/{browse.webp => builds.webp} (100%) create mode 100644 public/img/layout/new_boy_bg.png create mode 100644 public/img/layout/new_boy_dark.png create mode 100644 public/img/layout/new_girl_bg.png create mode 100644 public/img/layout/new_girl_dark.png delete mode 100644 window.d.ts diff --git a/app/components/Catcher.tsx b/app/components/Catcher.tsx index 7f25a3692..dd0dbe749 100644 --- a/app/components/Catcher.tsx +++ b/app/components/Catcher.tsx @@ -1,8 +1,8 @@ import { useCatch, useLocation } from "@remix-run/react"; -import { DISCORD_URL } from "~/constants"; import { getLogInUrl } from "~/utils"; import { useUser } from "~/hooks/common"; import { Button } from "./Button"; +import { discordUrl } from "~/utils/urls"; // TODO: some nice art export function Catcher() { @@ -18,7 +18,7 @@ export function Catcher() { {user ? (
If you need assistance you can ask for help on{" "} - + our Discord
diff --git a/app/components/Layout/DrawingSection.tsx b/app/components/Layout/DrawingSection.tsx new file mode 100644 index 000000000..28aa22749 --- /dev/null +++ b/app/components/Layout/DrawingSection.tsx @@ -0,0 +1,373 @@ +import clsx from "clsx"; +import randomColor from "randomcolor"; +import { useState } from "react"; + +interface HSL { + h: number; + s: number; + l: number; +} + +class Color { + public r: number; + public g: number; + public b: number; + constructor(r: number, g: number, b: number) { + this.r = this.clamp(r); + this.g = this.clamp(g); + this.b = this.clamp(b); + } + + toString() { + return `rgb(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round( + this.b + )})`; + } + + set(r: number, g: number, b: number) { + this.r = this.clamp(r); + this.g = this.clamp(g); + this.b = this.clamp(b); + } + + hueRotate(angle = 0) { + angle = (angle / 180) * Math.PI; + const sin = Math.sin(angle); + const cos = Math.cos(angle); + + this.multiply([ + 0.213 + cos * 0.787 - sin * 0.213, + 0.715 - cos * 0.715 - sin * 0.715, + 0.072 - cos * 0.072 + sin * 0.928, + 0.213 - cos * 0.213 + sin * 0.143, + 0.715 + cos * 0.285 + sin * 0.14, + 0.072 - cos * 0.072 - sin * 0.283, + 0.213 - cos * 0.213 - sin * 0.787, + 0.715 - cos * 0.715 + sin * 0.715, + 0.072 + cos * 0.928 + sin * 0.072, + ]); + } + + grayscale(value = 1) { + this.multiply([ + 0.2126 + 0.7874 * (1 - value), + 0.7152 - 0.7152 * (1 - value), + 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), + 0.7152 + 0.2848 * (1 - value), + 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), + 0.7152 - 0.7152 * (1 - value), + 0.0722 + 0.9278 * (1 - value), + ]); + } + + sepia(value = 1) { + this.multiply([ + 0.393 + 0.607 * (1 - value), + 0.769 - 0.769 * (1 - value), + 0.189 - 0.189 * (1 - value), + 0.349 - 0.349 * (1 - value), + 0.686 + 0.314 * (1 - value), + 0.168 - 0.168 * (1 - value), + 0.272 - 0.272 * (1 - value), + 0.534 - 0.534 * (1 - value), + 0.131 + 0.869 * (1 - value), + ]); + } + + saturate(value = 1) { + this.multiply([ + 0.213 + 0.787 * value, + 0.715 - 0.715 * value, + 0.072 - 0.072 * value, + 0.213 - 0.213 * value, + 0.715 + 0.285 * value, + 0.072 - 0.072 * value, + 0.213 - 0.213 * value, + 0.715 - 0.715 * value, + 0.072 + 0.928 * value, + ]); + } + + multiply(matrix: number[]) { + const newR = this.clamp( + this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2] + ); + const newG = this.clamp( + this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5] + ); + const newB = this.clamp( + this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8] + ); + this.r = newR; + this.g = newG; + this.b = newB; + } + + brightness(value = 1) { + this.linear(value); + } + contrast(value = 1) { + this.linear(value, -(0.5 * value) + 0.5); + } + + linear(slope = 1, intercept = 0) { + this.r = this.clamp(this.r * slope + intercept * 255); + this.g = this.clamp(this.g * slope + intercept * 255); + this.b = this.clamp(this.b * slope + intercept * 255); + } + + invert(value = 1) { + this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255); + this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255); + this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255); + } + + hsl(): HSL { + // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA. + const r = this.r / 255; + const g = this.g / 255; + const b = this.b / 255; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + + let h = 0; + let s = 0; + const l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + + case g: + h = (b - r) / d + 2; + break; + + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return { + h: h * 100, + s: s * 100, + l: l * 100, + }; + } + + clamp(value: number): number { + if (value > 255) { + value = 255; + } else if (value < 0) { + value = 0; + } + return value; + } +} +interface Solution { + loss: number; + values: number[]; +} +class Solver { + private target: Color; + private targetHSL: HSL; + private reusedColor: Color; + constructor(target: Color) { + this.target = target; + this.targetHSL = target.hsl(); + this.reusedColor = new Color(0, 0, 0); + } + + solve() { + const result = this.solveNarrow(this.solveWide()); + return { + values: result.values, + loss: result.loss, + filter: this.css(result.values), + }; + } + + solveWide(): Solution { + const A = 5; + const c = 15; + const a = [60, 180, 18000, 600, 1.2, 1.2]; + + let best = { loss: Infinity, values: [] as number[] }; + for (let i = 0; best.loss > 25 && i < 3; i++) { + const initial = [50, 20, 3750, 50, 100, 100]; + const result = this.spsa(A, a, c, initial, 1000); + if (result.loss < best.loss) { + best = result; + } + } + return best; + } + + solveNarrow(wide: Solution) { + const A = wide.loss; + const c = 2; + const A1 = A + 1; + const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1]; + return this.spsa(A, a, c, wide.values, 500); + } + + spsa( + A: number, + a: number[], + c: number, + values: number[], + iters: number + ): Solution { + const alpha = 1; + const gamma = 0.16666666666666666; + + let best = [] as number[]; + let bestLoss = Infinity; + const deltas = new Array(6); + const highArgs = new Array
+
+ Message: {data}
}If you need help or want to report the error so that it can be fixed - please visit our Discord + please visit our Discord
- Hello there! I appreciate you taking time to visit this beta version of - sendou.ink's Splatoon 3 site. This being a beta there is a few - things you should consider: -
-
z+-f4*DEm@o60&dEO(Dq^*&<9Rdl=cW^tqny`}_L5zmLyf@cMl2U+{3Q=ef>yo$FlZ
zI?wa8HqYQHOo3@|M2l{uw!~EleIKhqe?l>GvLf%gpTrp49-@1Ia=$p3jWAbD=M|Ig
ziX;sqB|7q)mUf$IoX6Vv$cMPviCepR<8CM1{$!6`_atZI{E7RXebkdChubaim-K#f
z>A6C;1a b!~v*12!|McF2Cw-g|;2kK`tu32xdSwxbTa;0}Te;~WPRc39PohMb
zhO@D`(dJlN2+$a1K%Y_ApRER1su^NINOiVTzasM4d*%dMIJ9EIJzZK;lLTT-&%ls3
zZe{!LcXO=quu|*oKdH}2?ne~eKX
z473;vJWT(VYEyan=ax=WWlar_<%8hBHQQV0+9VlrUa=3buhw!-P=Et5R{|U|`w=2G
zeN!6U7Bsbs?H`1u(?70Vn)f7eh7EM|IolP|83q|ytbpN_6E7AotbzS+IwS%1{6@!v
zf}5MWzrTOjhVOa%SH=hnp4ahxrWF$)0mq=GCebRJ=?|HosWH)Va&u*J$Nr`8T3hW-
z6cyMnG)$kKpS!xbxG+t+gs+koxrnAIu7U?ik8)e)-#0>W3kVUbye@8GQ#6=uJySTh
zxJSh%h9dR2%nW_QV9%)9=1Xg;9EvPKH