Drag me!
TSX
import React from "react";
import Draggable from 'react-draggable';
import classes from "./index.module.scss";
import clsx from "clsx";
interface GlassProps {
isDark?: boolean;
}
const Glass = ({ isDark = true }: GlassProps) => {
return (
<Draggable>
<div className={classes.Glass}>
<div className={classes['Glass-effect']} />
<div className={clsx(classes['Glass-tint'], isDark && classes['Glass-tint_dark'])} />
<div className={clsx(classes['Glass-shine'], isDark && classes['Glass-shine_dark'])} />
<svg style={{ display: 'none' }}>
<filter id="glass" filterUnits="objectBoundingBox">
<feTurbulence type="fractalNoise" baseFrequency="0.01 0.01" numOctaves="1" result="turbulence"seed="5" />
<feComponentTransfer in="turbulence" result="mapped">
<feFuncR amplitude="1" exponent="10" offset="0.5" type="gamma" />
<feFuncG amplitude="0" exponent="1" offset="0" type="gamma" />
<feFuncB amplitude="0" exponent="1" offset="0.5" type="gamma" />
</feComponentTransfer>
<feGaussianBlur in="turbulence" result="softMap" stdDeviation="2" />
<feSpecularLighting
in="softMap"
lightingColor="white"
result="specLight"
surfaceScale="5"
specularConstant="1"
specularExponent="100"
>
<fePointLight x="-200" y="-200" z="300" />
</feSpecularLighting>
<feComposite in="specLight" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litImage" />
<feDisplacementMap in="SourceGraphic" in2="softMap" scale="50" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
</div>
</Draggable>
);
};
export default Glass;
SCSS
.Glass {
border-radius: 1em;
box-shadow: 0 -1px 0 0 rgba(var(--theme-border-rgb), 0.15),
0 0 0 1px rgba(var(--theme-border-rgb), 0.15);
cursor: grab;
height: 100px;
overflow: hidden;
position: relative;
width: 100px;
z-index: 1000;
&-effect,
&-tint,
&-shine {
inset: 0;
overflow: hidden;
pointer-events: none;
position: absolute;
}
&-effect {
backdrop-filter: blur(0.25em);
filter: url("#glass");
isolation: isolate;
z-index: -2;
}
&-tint {
--Glass-tint: rgba(var(--theme-bg-rgb), 0.7);
background: var(--Glass-tint);
z-index: -1;
&_dark {
--Glass-tint: rgba(var(--theme-bg-rgb), 0.1);
}
}
&-shine {
--Glass-shine-gradient: linear-gradient(
135deg,
var(--purple),
var(--blue),
var(--green),
var(--yellow),
var(--red)
);
--Glass-shine: inset 2px 2px 1px 0 rgba(white, 0.075),
inset -1px -1px 1px 1px rgba(white, 0.075);
--Glass-shine-opacity: 0.1;
box-shadow: var(--Glass-shine);
z-index: 0;
&_dark {
--Glass-shine: inset 2px 2px 1px 0 rgba(black, 0.075),
inset -1px -1px 1px 1px rgba(black, 0.075);
--Glass-shine-opacity: 0.1;
}
&::before {
background: var(--Glass-shine-gradient);
content: "";
display: block;
inset: 0;
mask-image: linear-gradient(to top, rgba(black, 1), rgba(black, 0));
opacity: var(--Glass-shine-opacity);
position: absolute;
z-index: 5;
}
}
}