TelegramPWA/src/components/common/MediaSpoiler.module.scss
2025-10-15 19:57:16 +02:00

182 lines
3.5 KiB
SCSS

.root {
--click-shift-x: 0px;
--click-shift-y: 0px;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: var(--color-text-secondary); // Fallback before canvas is prepared
}
.mask-animation:global(.closing) {
-webkit-mask-composite: destination-out;
mask-composite: exclude;
mask-image: url("../../assets/spoilers/mask.svg"), linear-gradient(#ffffff, #ffffff);
mask-position: calc(50% + var(--click-shift-x)) calc(50% + var(--click-shift-y)), center center;
mask-repeat: no-repeat;
mask-size: 0%;
:global(body:not(.no-page-transitions)) & {
animation: 500ms ease-in circle-cut forwards;
}
.dots {
transform: scale(1.2);
}
}
.canvas {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.nsfw {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
gap: 0.25rem;
align-items: center;
padding: 0.125rem 0.5rem;
border-radius: 1rem;
color: white;
background-color: rgba(0, 0, 0, 0.25);
}
.nsfwIcon {
font-size: 1.25rem;
}
.dots {
--x-direction: var(--background-size);
--y-direction: 0;
--background-url: url("../../assets/spoilers/turbulence_1x.png");
--background-size: 256px;
position: absolute;
top: 0;
left: 0;
transform-origin: calc(50% + var(--click-shift-x)) calc(50% + var(--click-shift-y));
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.25) var(--background-url);
background-size: var(--background-size) var(--background-size);
transition: transform 500ms ease-in;
&::before {
--x-direction: 0;
--y-direction: var(--background-size);
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--background-url);
background-position: calc(var(--x-direction) / 2) calc(var(--y-direction) / 2);
background-size: var(--background-size) var(--background-size);
animation: 2s linear -0.8s infinite opacity-breath;
}
&::after {
--x-direction: calc(-1 * var(--background-size));
--y-direction: calc(-1 * var(--background-size));
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: var(--background-url);
background-position: calc(var(--x-direction) / 2) calc(var(--y-direction) / 2);
background-size: var(--background-size) var(--background-size);
animation: 2s linear -1.5s infinite opacity-breath;
}
@media (-webkit-min-device-pixel-ratio: 2) {
--background-url: url("../../assets/spoilers/turbulence_2x.png");
}
@media (-webkit-min-device-pixel-ratio: 3) {
--background-url: url("../../assets/spoilers/turbulence_3x.png");
}
}
:global(body:not(.no-page-transitions)) .dots {
animation: 20s linear infinite;
animation-name: dots-animation;
&::before {
animation: 21s linear -7s infinite;
animation-name: dots-animation;
}
&::after {
animation: 22s linear -14s infinite;
animation-name: dots-animation;
}
}
:global(body.in-background) .dots {
&, &::before, &::after {
animation-play-state: paused;
}
}
@keyframes dots-animation {
0% {
background-position: 0 0;
}
100% {
background-position: var(--x-direction) var(--y-direction);
}
}
@keyframes circle-cut {
0% {
mask-size: 0%, 100%;
}
100% {
mask-size: 350%, 100%;
}
}
@keyframes opacity-breath {
0% {
opacity: 1;
}
50% {
opacity: 0.1;
}
100% {
opacity: 1;
}
}