Scanline modifications, change default weather channel branding to a slackware linux style weather branding
1
.gitignore
vendored
|
|
@ -15,3 +15,4 @@ dist/*
|
||||||
|
|
||||||
#environment variables
|
#environment variables
|
||||||
.env
|
.env
|
||||||
|
nohup.out
|
||||||
|
|
|
||||||
36
package-lock.json
generated
|
|
@ -1551,9 +1551,6 @@
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -1575,9 +1572,6 @@
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -1599,9 +1593,6 @@
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -1623,9 +1614,6 @@
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -1647,9 +1635,6 @@
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -1671,9 +1656,6 @@
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|
@ -3466,9 +3448,9 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.12",
|
"version": "1.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
|
||||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -5320,9 +5302,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/filelist/node_modules/brace-expansion": {
|
"node_modules/filelist/node_modules/brace-expansion": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz",
|
||||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
"integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7575,9 +7557,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.23",
|
"version": "4.18.1",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
|
||||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
"integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 422 KiB |
BIN
server/images/backgrounds/1.png.old
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 420 KiB |
BIN
server/images/backgrounds/2.png.old
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 9.4 KiB |
BIN
server/images/logos/logo-corner.png.original
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
|
|
@ -1,130 +1,243 @@
|
||||||
/* REGULAR SCANLINES SETTINGS */
|
/* =========================================================
|
||||||
|
REGULAR SCANLINES SETTINGS
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
// width of 1 scanline (responsive units to prevent banding)
|
|
||||||
$scan-width: 1px;
|
$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;
|
$scan-crt: false;
|
||||||
|
|
||||||
// frames-per-second (should be > 1), only applies if $scan-crt: true;
|
|
||||||
$scan-fps: 20;
|
$scan-fps: 20;
|
||||||
|
$scan-color: rgba(#000, 0.30);
|
||||||
// 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;
|
$scan-z-index: 2147483648;
|
||||||
|
|
||||||
/* MOVING SCANLINE SETTINGS */
|
|
||||||
|
|
||||||
// moving scanline (true, false)
|
|
||||||
$scan-moving-line: true;
|
$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);
|
// mild brightening / contrast to keep blur from looking muddy
|
||||||
@mixin scan-crt($scan-crt) {
|
$crt-contrast: 1.04;
|
||||||
@if $scan-crt==true {
|
$crt-saturation: 1.08;
|
||||||
animation: scanlines 1s steps($scan-fps) infinite;
|
$crt-brightness: 0.98;
|
||||||
}
|
|
||||||
|
|
||||||
@else {
|
// fake horizontal chroma bleed
|
||||||
animation: none;
|
$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($enabled) {
|
||||||
@mixin scan-moving($scan-moving-line) {
|
@if $enabled == true {
|
||||||
@if $scan-moving-line==true {
|
animation: scanline 6s linear infinite;
|
||||||
animation: scanline 6s linear infinite;
|
} @else {
|
||||||
}
|
animation: none;
|
||||||
|
}
|
||||||
@else {
|
|
||||||
animation: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CSS .scanlines CLASS */
|
/* =========================================================
|
||||||
|
APPLY TO THE REAL APP CONTAINER
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
/*
|
||||||
|
You can add class="scanlines" to #divTwcMain or #container.
|
||||||
|
Example:
|
||||||
|
<div id="divTwcMain" class="scanlines">
|
||||||
|
*/
|
||||||
|
|
||||||
.scanlines {
|
.scanlines {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden; // only to animate the unique scanline
|
overflow: hidden;
|
||||||
|
isolation: isolate;
|
||||||
|
|
||||||
&:before,
|
/*
|
||||||
&:after {
|
This is the actual rendered weather area in your HTML.
|
||||||
display: block;
|
Applying the softness here affects the maps/text/icons themselves.
|
||||||
pointer-events: none;
|
*/
|
||||||
content: '';
|
#container {
|
||||||
position: absolute;
|
position: relative;
|
||||||
}
|
z-index: 1;
|
||||||
|
transform: translateZ(0);
|
||||||
|
will-change: filter;
|
||||||
|
|
||||||
// unique scanline travelling on the screen
|
filter:
|
||||||
&:before {
|
blur($crt-soft-blur)
|
||||||
// position: absolute;
|
saturate($crt-saturation)
|
||||||
// bottom: 100%;
|
contrast($crt-contrast)
|
||||||
width: 100%;
|
brightness($crt-brightness);
|
||||||
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 {
|
Red fringe overlay
|
||||||
top: 0;
|
*/
|
||||||
right: 0;
|
#container::before,
|
||||||
bottom: 0;
|
#container::after {
|
||||||
left: 0;
|
content: '';
|
||||||
z-index: $scan-z-index;
|
position: absolute;
|
||||||
// repeating-linear-gradient is more efficient than linear-gradient+background-size because it doesn't require the browser to calculate tiling
|
inset: 0;
|
||||||
background: repeating-linear-gradient(to bottom,
|
pointer-events: none;
|
||||||
transparent 0,
|
z-index: 3;
|
||||||
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
|
#container::before {
|
||||||
image-rendering: crisp-edges;
|
background:
|
||||||
image-rendering: pixelated;
|
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
|
Blue fringe overlay
|
||||||
// The --scanline-thickness custom property is set by applyScanlineScaling()
|
*/
|
||||||
// The modes (hairline, thin, medium, thick) force the base thickness selection
|
#container::after {
|
||||||
// Some modes may appear the same (e.g. hairline and thin) depending on the display
|
background:
|
||||||
&:before {
|
linear-gradient(
|
||||||
height: var(--scanline-thickness, $scan-width);
|
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,
|
Moving scanline
|
||||||
transparent 0,
|
*/
|
||||||
transparent var(--scanline-thickness, $scan-width),
|
&:before,
|
||||||
$scan-color var(--scanline-thickness, $scan-width),
|
&:after {
|
||||||
$scan-color calc(var(--scanline-thickness, $scan-width) * 2));
|
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 {
|
@keyframes scanline {
|
||||||
0% {
|
0% {
|
||||||
transform: translate3d(0, 200000%, 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 {
|
@keyframes scanlines {
|
||||||
0% {
|
0% {
|
||||||
background-position: 0 50%;
|
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%; }
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
130
server/styles/scss/shared/_scanlines.scss.old
Normal file
|
|
@ -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%; }
|
||||||
|
}
|
||||||
|
}
|
||||||