diff --git a/.gitignore b/.gitignore index 7ed4bca..e758bf9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ dist/* !dist/readme.txt #environment variables -.env \ No newline at end of file +.env +nohup.out diff --git a/package-lock.json b/package-lock.json index a17bcf4..42bc6e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1551,9 +1551,6 @@ "arm" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1575,9 +1572,6 @@ "arm" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1599,9 +1593,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1623,9 +1614,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1647,9 +1635,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1671,9 +1656,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3466,9 +3448,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5320,9 +5302,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -7575,9 +7557,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, diff --git a/server/images/backgrounds/1.png b/server/images/backgrounds/1.png index c5b0870..d2986c5 100644 Binary files a/server/images/backgrounds/1.png and b/server/images/backgrounds/1.png differ diff --git a/server/images/backgrounds/1.png.old b/server/images/backgrounds/1.png.old new file mode 100644 index 0000000..c5b0870 Binary files /dev/null and b/server/images/backgrounds/1.png.old differ diff --git a/server/images/backgrounds/2.png b/server/images/backgrounds/2.png index adcdebc..ccb9b22 100644 Binary files a/server/images/backgrounds/2.png and b/server/images/backgrounds/2.png differ diff --git a/server/images/backgrounds/2.png.old b/server/images/backgrounds/2.png.old new file mode 100644 index 0000000..adcdebc Binary files /dev/null and b/server/images/backgrounds/2.png.old differ diff --git a/server/images/logos/logo-corner.png b/server/images/logos/logo-corner.png index cce7cd4..3e9862f 100644 Binary files a/server/images/logos/logo-corner.png and b/server/images/logos/logo-corner.png differ diff --git a/server/images/logos/logo-corner.png.original b/server/images/logos/logo-corner.png.original new file mode 100644 index 0000000..cce7cd4 Binary files /dev/null and b/server/images/logos/logo-corner.png.original differ diff --git a/server/styles/scss/shared/_scanlines.scss b/server/styles/scss/shared/_scanlines.scss index 66636f1..783fddb 100644 --- a/server/styles/scss/shared/_scanlines.scss +++ b/server/styles/scss/shared/_scanlines.scss @@ -1,130 +1,243 @@ -/* REGULAR SCANLINES SETTINGS */ +/* ========================================================= + REGULAR SCANLINES SETTINGS + ========================================================= */ -// width of 1 scanline (responsive units to prevent banding) $scan-width: 1px; -$scan-width-scaled: 0.15vh; // viewport-relative unit for better scaling - -// emulates a damage-your-eyes bad pre-2000 CRT screen ♥ (true, false) $scan-crt: false; - -// frames-per-second (should be > 1), only applies if $scan-crt: true; $scan-fps: 20; - -// scanline-color (rgba) -$scan-color: rgba(#000, .3); - -// set z-index on 8, like in ♥ 8-bits ♥, or… -// set z-index on 2147483648 or more to enable scanlines on Chrome fullscreen (doesn't work in Firefox or IE); +$scan-color: rgba(#000, 0.30); $scan-z-index: 2147483648; -/* MOVING SCANLINE SETTINGS */ - -// moving scanline (true, false) $scan-moving-line: true; +$scan-opacity: 0.75; -// opacity of the moving scanline -$scan-opacity: .75; +/* ========================================================= + CRT / S-VIDEO EFFECT SETTINGS + ========================================================= */ -/* MIXINS */ +// whole-screen softness +$crt-soft-blur: 0.45px; -// apply CRT animation: @include scan-crt($scan-crt); -@mixin scan-crt($scan-crt) { - @if $scan-crt==true { - animation: scanlines 1s steps($scan-fps) infinite; - } +// mild brightening / contrast to keep blur from looking muddy +$crt-contrast: 1.04; +$crt-saturation: 1.08; +$crt-brightness: 0.98; - @else { - animation: none; - } +// fake horizontal chroma bleed +$crt-r-shift: -0.7px; +$crt-b-shift: 0.7px; +$crt-bleed-blur: 1.2px; +$crt-rgb-opacity: 0.04; + +// subtle tube edge darkening +$crt-vignette-opacity: 0.16; + +// optional tiny bloom +$crt-glow-opacity: 0.05; + +/* ========================================================= + MIXINS + ========================================================= */ + +@mixin scan-crt($enabled) { + @if $enabled == true { + animation: scanlines 1s steps($scan-fps) infinite; + } @else { + animation: none; + } } -// apply CRT animation: @include scan-crt($scan-crt); -@mixin scan-moving($scan-moving-line) { - @if $scan-moving-line==true { - animation: scanline 6s linear infinite; - } - - @else { - animation: none; - } +@mixin scan-moving($enabled) { + @if $enabled == true { + animation: scanline 6s linear infinite; + } @else { + animation: none; + } } -/* CSS .scanlines CLASS */ +/* ========================================================= + APPLY TO THE REAL APP CONTAINER + ========================================================= */ + +/* + You can add class="scanlines" to #divTwcMain or #container. + Example: +
+*/ .scanlines { - position: relative; - overflow: hidden; // only to animate the unique scanline + position: relative; + overflow: hidden; + isolation: isolate; - &:before, - &:after { - display: block; - pointer-events: none; - content: ''; - position: absolute; - } + /* + This is the actual rendered weather area in your HTML. + Applying the softness here affects the maps/text/icons themselves. + */ + #container { + position: relative; + z-index: 1; + transform: translateZ(0); + will-change: filter; - // unique scanline travelling on the screen - &:before { - // position: absolute; - // bottom: 100%; - width: 100%; - height: $scan-width * 1; - z-index: $scan-z-index + 1; - background: $scan-color; - opacity: $scan-opacity; - // animation: scanline 6s linear infinite; - @include scan-moving($scan-moving-line); - } + filter: + blur($crt-soft-blur) + saturate($crt-saturation) + contrast($crt-contrast) + brightness($crt-brightness); + } - // the scanlines, so! - with responsive scaling for low-res displays - &:after { - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: $scan-z-index; - // repeating-linear-gradient is more efficient than linear-gradient+background-size because it doesn't require the browser to calculate tiling - background: repeating-linear-gradient(to bottom, - transparent 0, - transparent $scan-width, - $scan-color $scan-width, - $scan-color calc($scan-width * 2)); - @include scan-crt($scan-crt); + /* + Red fringe overlay + */ + #container::before, + #container::after { + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + z-index: 3; + } - // Prevent sub-pixel aliasing on scaled displays - image-rendering: crisp-edges; - image-rendering: pixelated; - } + #container::before { + background: + linear-gradient( + to right, + rgba(255, 0, 0, $crt-rgb-opacity) 0%, + rgba(255, 0, 0, 0.01) 15%, + rgba(255, 0, 0, 0.00) 50%, + rgba(255, 0, 0, 0.01) 85%, + rgba(255, 0, 0, $crt-rgb-opacity) 100% + ); + transform: translateX($crt-r-shift); + filter: blur($crt-bleed-blur); + mix-blend-mode: screen; + } - // Scanlines use dynamic thickness calculated by JavaScript - // JavaScript calculates optimal thickness to prevent banding at any scale factor - // The --scanline-thickness custom property is set by applyScanlineScaling() - // The modes (hairline, thin, medium, thick) force the base thickness selection - // Some modes may appear the same (e.g. hairline and thin) depending on the display - &:before { - height: var(--scanline-thickness, $scan-width); - } + /* + Blue fringe overlay + */ + #container::after { + background: + linear-gradient( + to right, + rgba(0, 140, 255, $crt-rgb-opacity) 0%, + rgba(0, 140, 255, 0.01) 15%, + rgba(0, 140, 255, 0.00) 50%, + rgba(0, 140, 255, 0.01) 85%, + rgba(0, 140, 255, $crt-rgb-opacity) 100% + ); + transform: translateX($crt-b-shift); + filter: blur($crt-bleed-blur); + mix-blend-mode: screen; + } - &:after { - background: repeating-linear-gradient(to bottom, - transparent 0, - transparent var(--scanline-thickness, $scan-width), - $scan-color var(--scanline-thickness, $scan-width), - $scan-color calc(var(--scanline-thickness, $scan-width) * 2)); - } + /* + Moving scanline + */ + &:before, + &:after { + display: block; + pointer-events: none; + content: ''; + position: absolute; + left: 0; + right: 0; + } + + &:before { + height: var(--scanline-thickness, $scan-width); + z-index: $scan-z-index + 2; + background: $scan-color; + opacity: $scan-opacity; + @include scan-moving($scan-moving-line); + } + + /* + Regular scanline mask + */ + &:after { + top: 0; + bottom: 0; + z-index: $scan-z-index; + background: repeating-linear-gradient( + to bottom, + transparent 0, + transparent var(--scanline-thickness, $scan-width), + $scan-color var(--scanline-thickness, $scan-width), + $scan-color calc(var(--scanline-thickness, $scan-width) * 2) + ); + @include scan-crt($scan-crt); + } + + /* + Vignette layer + Added as an inset shadow so you don't need extra HTML + */ + box-shadow: + inset 0 0 80px rgba(0, 0, 0, $crt-vignette-opacity), + inset 0 0 18px rgba(255, 255, 255, $crt-glow-opacity); } -/* ANIMATE UNIQUE SCANLINE */ +/* ========================================================= + OPTIONAL: only affect active weather panels, not menus + ========================================================= */ + +/* + If the controls / bottom nav get too blurry, move the blur + from #container to the weather slides only: +*/ +.scanlines.crt-panels-only { + #container { + filter: none; + } + + .weather-display { + filter: + blur($crt-soft-blur) + saturate($crt-saturation) + contrast($crt-contrast) + brightness($crt-brightness); + + transform: translateZ(0); + } +} + +/* ========================================================= + OPTIONAL: make text slightly glow like old TV phosphors + ========================================================= */ + +.scanlines { + .header, + .main, + .scroll, + .date-time, + .city, + .temp, + .condition, + .location, + .label, + .value, + .title { + text-shadow: + 0 0 1px rgba(255, 255, 255, 0.18), + 0 0 2px rgba(255, 255, 255, 0.06); + } +} + +/* ========================================================= + ANIMATIONS + ========================================================= */ + @keyframes scanline { - 0% { - transform: translate3d(0, 200000%, 0); - // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; } - } + 0% { + transform: translate3d(0, 200000%, 0); + } } @keyframes scanlines { - 0% { - background-position: 0 50%; - // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; } - } + 0% { + background-position: 0 50%; + } } + diff --git a/server/styles/scss/shared/_scanlines.scss.old b/server/styles/scss/shared/_scanlines.scss.old new file mode 100644 index 0000000..66636f1 --- /dev/null +++ b/server/styles/scss/shared/_scanlines.scss.old @@ -0,0 +1,130 @@ +/* REGULAR SCANLINES SETTINGS */ + +// width of 1 scanline (responsive units to prevent banding) +$scan-width: 1px; +$scan-width-scaled: 0.15vh; // viewport-relative unit for better scaling + +// emulates a damage-your-eyes bad pre-2000 CRT screen ♥ (true, false) +$scan-crt: false; + +// frames-per-second (should be > 1), only applies if $scan-crt: true; +$scan-fps: 20; + +// scanline-color (rgba) +$scan-color: rgba(#000, .3); + +// set z-index on 8, like in ♥ 8-bits ♥, or… +// set z-index on 2147483648 or more to enable scanlines on Chrome fullscreen (doesn't work in Firefox or IE); +$scan-z-index: 2147483648; + +/* MOVING SCANLINE SETTINGS */ + +// moving scanline (true, false) +$scan-moving-line: true; + +// opacity of the moving scanline +$scan-opacity: .75; + +/* MIXINS */ + +// apply CRT animation: @include scan-crt($scan-crt); +@mixin scan-crt($scan-crt) { + @if $scan-crt==true { + animation: scanlines 1s steps($scan-fps) infinite; + } + + @else { + animation: none; + } +} + +// apply CRT animation: @include scan-crt($scan-crt); +@mixin scan-moving($scan-moving-line) { + @if $scan-moving-line==true { + animation: scanline 6s linear infinite; + } + + @else { + animation: none; + } +} + +/* CSS .scanlines CLASS */ + +.scanlines { + position: relative; + overflow: hidden; // only to animate the unique scanline + + &:before, + &:after { + display: block; + pointer-events: none; + content: ''; + position: absolute; + } + + // unique scanline travelling on the screen + &:before { + // position: absolute; + // bottom: 100%; + width: 100%; + height: $scan-width * 1; + z-index: $scan-z-index + 1; + background: $scan-color; + opacity: $scan-opacity; + // animation: scanline 6s linear infinite; + @include scan-moving($scan-moving-line); + } + + // the scanlines, so! - with responsive scaling for low-res displays + &:after { + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $scan-z-index; + // repeating-linear-gradient is more efficient than linear-gradient+background-size because it doesn't require the browser to calculate tiling + background: repeating-linear-gradient(to bottom, + transparent 0, + transparent $scan-width, + $scan-color $scan-width, + $scan-color calc($scan-width * 2)); + @include scan-crt($scan-crt); + + // Prevent sub-pixel aliasing on scaled displays + image-rendering: crisp-edges; + image-rendering: pixelated; + } + + // Scanlines use dynamic thickness calculated by JavaScript + // JavaScript calculates optimal thickness to prevent banding at any scale factor + // The --scanline-thickness custom property is set by applyScanlineScaling() + // The modes (hairline, thin, medium, thick) force the base thickness selection + // Some modes may appear the same (e.g. hairline and thin) depending on the display + &:before { + height: var(--scanline-thickness, $scan-width); + } + + &:after { + background: repeating-linear-gradient(to bottom, + transparent 0, + transparent var(--scanline-thickness, $scan-width), + $scan-color var(--scanline-thickness, $scan-width), + $scan-color calc(var(--scanline-thickness, $scan-width) * 2)); + } +} + +/* ANIMATE UNIQUE SCANLINE */ +@keyframes scanline { + 0% { + transform: translate3d(0, 200000%, 0); + // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; } + } +} + +@keyframes scanlines { + 0% { + background-position: 0 50%; + // bottom: 0%; // to have a continuous scanline move, use this line (here in 0% step) instead of transform and write, in &:before, { position: absolute; bottom: 100%; } + } +}