Created
December 21, 2023 22:29
-
-
Save danieledler/294695cf778e3375609bfa722efd3285 to your computer and use it in GitHub Desktop.
Proximity Glow Cards
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="container"> | |
<article> | |
<div class="glows"></div> | |
<span class="header"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
</span> | |
<span class="badge"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M9 4.5a.75.75 0 01.721.544l.813 2.846a3.75 3.75 0 002.576 2.576l2.846.813a.75.75 0 010 1.442l-2.846.813a3.75 3.75 0 00-2.576 2.576l-.813 2.846a.75.75 0 01-1.442 0l-.813-2.846a3.75 3.75 0 00-2.576-2.576l-2.846-.813a.75.75 0 010-1.442l2.846-.813A3.75 3.75 0 007.466 7.89l.813-2.846A.75.75 0 019 4.5zM18 1.5a.75.75 0 01.728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 010 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 01-1.456 0l-.258-1.036a2.625 2.625 0 00-1.91-1.91l-1.036-.258a.75.75 0 010-1.456l1.036-.258a2.625 2.625 0 001.91-1.91l.258-1.036A.75.75 0 0118 1.5zM16.5 15a.75.75 0 01.712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 010 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 01-1.422 0l-.395-1.183a1.5 1.5 0 00-.948-.948l-1.183-.395a.75.75 0 010-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0116.5 15z" clip-rule="evenodd" /> | |
</svg> | |
<span>Pointer tracking glows</span> | |
</span> | |
<h2>Wherever you go,<br>it follows</h2> | |
<a href="">Learn more</a> | |
</article> | |
<article> | |
<div class="glows"></div> | |
<span class="header"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M17.303 5.197A7.5 7.5 0 006.697 15.803a.75.75 0 01-1.061 1.061A9 9 0 1121 10.5a.75.75 0 01-1.5 0c0-1.92-.732-3.839-2.197-5.303zm-2.121 2.121a4.5 4.5 0 00-6.364 6.364.75.75 0 11-1.06 1.06A6 6 0 1118 10.5a.75.75 0 01-1.5 0c0-1.153-.44-2.303-1.318-3.182zm-3.634 1.314a.75.75 0 01.82.311l5.228 7.917a.75.75 0 01-.777 1.148l-2.097-.43 1.045 3.9a.75.75 0 01-1.45.388l-1.044-3.899-1.601 1.42a.75.75 0 01-1.247-.606l.569-9.47a.75.75 0 01.554-.68z" clip-rule="evenodd" /> | |
</svg> | |
</span> | |
<span class="badge"> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="w-6 h-6"> | |
<path fill-rule="evenodd" d="M9 4.5a.75.75 0 01.721.544l.813 2.846a3.75 3.75 0 002.576 2.576l2.846.813a.75.75 0 010 1.442l-2.846.813a3.75 3.75 0 00-2.576 2.576l-.813 2.846a.75.75 0 01-1.442 0l-.813-2.846a3.75 3.75 0 00-2.576-2.576l-2.846-.813a.75.75 0 010-1.442l2.846-.813A3.75 3.75 0 007.466 7.89l.813-2.846A.75.75 0 019 4.5zM18 1.5a.75.75 0 01.728.568l.258 1.036c.236.94.97 1.674 1.91 1.91l1.036.258a.75.75 0 010 1.456l-1.036.258c-.94.236-1.674.97-1.91 1.91l-.258 1.036a.75.75 0 01-1.456 0l-.258-1.036a2.625 2.625 0 00-1.91-1.91l-1.036-.258a.75.75 0 010-1.456l1.036-.258a2.625 2.625 0 001.91-1.91l.258-1.036A.75.75 0 0118 1.5zM16.5 15a.75.75 0 01.712.513l.394 1.183c.15.447.5.799.948.948l1.183.395a.75.75 0 010 1.422l-1.183.395c-.447.15-.799.5-.948.948l-.395 1.183a.75.75 0 01-1.422 0l-.395-1.183a1.5 1.5 0 00-.948-.948l-1.183-.395a.75.75 0 010-1.422l1.183-.395c.447-.15.799-.5.948-.948l.395-1.183A.75.75 0 0116.5 15z" clip-rule="evenodd" /> | |
</svg> | |
<span>Pointer tracking glows</span> | |
</span> | |
<h2>Activate by,<br>getting closer</h2> | |
<a href="">Learn more</a> | |
</article> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GUI } from 'https://cdn.skypack.dev/dat.gui' | |
const CONTAINER = document.querySelector('.container') | |
const CARDS = document.querySelectorAll('article') | |
const CONFIG = { | |
proximity: 40, | |
spread: 80, | |
blur: 20, | |
gap: 32, | |
vertical: false, | |
opacity: 0, | |
} | |
const PROXIMITY = 10 | |
const UPDATE = (event) => { | |
// get the angle based on the center point of the card and pointer position | |
for (const CARD of CARDS) { | |
// Check the card against the proximity and then start updating | |
const CARD_BOUNDS = CARD.getBoundingClientRect() | |
// Get distance between pointer and outerbounds of card | |
if ( | |
event?.x > CARD_BOUNDS.left - CONFIG.proximity && | |
event?.x < CARD_BOUNDS.left + CARD_BOUNDS.width + CONFIG.proximity && | |
event?.y > CARD_BOUNDS.top - CONFIG.proximity && | |
event?.y < CARD_BOUNDS.top + CARD_BOUNDS.height + CONFIG.proximity) { | |
// If within proximity set the active opacity | |
CARD.style.setProperty('--active', 1) | |
} else { | |
CARD.style.setProperty('--active', CONFIG.opacity) | |
} | |
const CARD_CENTER = [ | |
CARD_BOUNDS.left + CARD_BOUNDS.width * 0.5, | |
CARD_BOUNDS.top + CARD_BOUNDS.height * 0.5 | |
] | |
let ANGLE = Math.atan2(event?.y - CARD_CENTER[1], event?.x - CARD_CENTER[0]) * 180 / Math.PI | |
ANGLE = ANGLE < 0 ? ANGLE + 360 : ANGLE; | |
CARD.style.setProperty('--start', ANGLE + 90) | |
} | |
} | |
document.body.addEventListener('pointermove', UPDATE) | |
const RESTYLE = () => { | |
CONTAINER.style.setProperty('--gap', CONFIG.gap) | |
CONTAINER.style.setProperty('--blur', CONFIG.blur) | |
CONTAINER.style.setProperty('--spread', CONFIG.spread) | |
CONTAINER.style.setProperty('--direction', CONFIG.vertical ? 'column' : 'row') | |
} | |
const CTRL = new GUI({ | |
width: 340, | |
}) | |
CTRL.add(CONFIG, 'spread', 10, 180, 1).name('Spread (deg)').onChange(RESTYLE) | |
CTRL.add(CONFIG, 'proximity', 10, 180, 1).name('Active Proximity (px)').onChange(RESTYLE) | |
CTRL.add(CONFIG, 'gap', 10, 100, 1).name('Gap (px)').onChange(RESTYLE) | |
CTRL.add(CONFIG, 'blur', 0, 50, 1).name('Blur (px)').onChange(RESTYLE) | |
CTRL.add(CONFIG, 'opacity', 0, 1, 0.01).name('Inactive Opacity').onChange(RESTYLE) | |
CTRL.add(CONFIG, 'vertical').name('Vertical Layout').onChange(RESTYLE) | |
RESTYLE() | |
UPDATE() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "normalize.css"; | |
@font-face { | |
font-family: "Geist Sans"; | |
src: url("https://assets.codepen.io/605876/GeistVF.ttf") format("truetype"); | |
} | |
:root { | |
--bg: hsl(246 44% 7%); | |
--border: hsl(280 10% 50% / 1); | |
--card: hsl(237 36% 10%); | |
--color: hsl(240 18% 80%); | |
--border-width: 2px; | |
--border-radius: 12px; | |
--gradient: conic-gradient(from 180deg at 50% 70%,hsla(0,0%,98%,1) 0deg,#eec32d 72.0000010728836deg,#ec4b4b 144.0000021457672deg,#709ab9 216.00000858306885deg,#4dffbf 288.0000042915344deg,hsla(0,0%,98%,1) 1turn); | |
} | |
*, | |
*:after, | |
*:before { | |
box-sizing: border-box; | |
} | |
@property --start { | |
syntax: '<number>'; | |
inherits: true; | |
initial-value: 0; | |
} | |
body { | |
background: var(--bg); | |
display: grid; | |
place-items: center; | |
min-height: 100vh; | |
font-family: "Geist Sans", "SF Pro Text", "SF Pro Icons", "AOS Icons", "Helvetica Neue", Helvetica, Arial, sans-serif, system-ui; | |
font-weight: 70; | |
color: var(--color); | |
} | |
.container { | |
--spread: 60; | |
display: flex; | |
flex-wrap: wrap; | |
flex-direction: var(--direction); | |
gap: calc(var(--gap) * 1px); | |
margin: 0 auto; | |
justify-content: center; | |
place-items: center; | |
position: relative; | |
padding: 2rem; | |
touch-action: none; | |
} | |
article { | |
--active: 0.15; | |
--start: 0; | |
height: 100%; | |
background: var(--card); | |
padding: 2rem; | |
aspect-ratio: 330 / 400; | |
border-radius: var(--border-radius); | |
min-width: 280px; | |
max-width: 280px; | |
display: flex; | |
flex-direction: column; | |
gap: 0.25rem; | |
position: relative; | |
} | |
article:is(:hover, :focus-visible) { | |
z-index: 2; | |
} | |
.glows { | |
pointer-events: none; | |
position: absolute; | |
inset: 0; | |
filter: blur(calc(var(--blur) * 1px)); | |
} | |
.glows::after, | |
.glows::before { | |
--alpha: 0; | |
content: ""; | |
background: var(--gradient); | |
background-attachment: fixed; | |
position: absolute; | |
inset: -5px; | |
border: 10px solid transparent; | |
border-radius: var(--border-radius); | |
mask: | |
linear-gradient(#0000, #0000), | |
conic-gradient(from calc((var(--start) - (var(--spread) * 0.5)) * 1deg), #000 0deg, #fff, #0000 calc(var(--spread) * 1deg)); | |
mask-composite: intersect; | |
mask-clip: padding-box, border-box; | |
opacity: var(--active); | |
transition: opacity 1s; | |
} | |
article::before { | |
position: absolute; | |
inset: 0; | |
border: var(--border-width) solid transparent; | |
content: ""; | |
border-radius: var(--border-radius); | |
pointer-events: none; | |
background: var(--border); | |
background-attachment: fixed; | |
border-radius: var(--border-radius); | |
mask: | |
linear-gradient(#0000, #0000), | |
conic-gradient( | |
from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 1.5)) * 1deg), | |
hsl(0 0% 100% / 0.15) 0deg, | |
white, | |
hsl(0 0% 100% / 0.15) calc(var(--spread) * 2.5deg)); | |
mask-clip: padding-box, border-box; | |
mask-composite: intersect; | |
opacity: var(--active); | |
transition: opacity 1s; | |
} | |
article::after { | |
--bg-size: 100%; | |
content: ""; | |
pointer-events: none; | |
position: absolute; | |
background: var(--gradient); | |
background-attachment: fixed; | |
border-radius: var(--border-radius); | |
opacity: var(--active, 0); | |
transition: opacity 1s; | |
--alpha: 0; | |
inset: 0; | |
border: var(--border-width) solid transparent; | |
mask: | |
linear-gradient(#0000, #0000), | |
conic-gradient(from calc(((var(--start) + (var(--spread) * 0.25)) - (var(--spread) * 0.5)) * 1deg), #0000 0deg, #fff, #0000 calc(var(--spread) * 0.5deg)); | |
filter: brightness(1.5); | |
mask-clip: padding-box, border-box; | |
mask-composite: intersect; | |
} | |
.badge { | |
border: 2px solid var(--border); | |
align-self: start; | |
border-radius: 100px; | |
padding: 0.5rem 0.7rem; | |
font-size: 0.675rem; | |
display: flex; | |
align-items: center; | |
gap: 0.25rem; | |
font-weight: 50; | |
} | |
a { | |
color: var(--color); | |
text-decoration: none; | |
opacity: 0.5; | |
display: inline-block; | |
align-self: start; | |
transition: opacity 0.2s; | |
} | |
a:is(:hover, :focus-visible) { | |
opacity: 1; | |
} | |
article h2 { | |
margin: 0; | |
padding: 1rem 0; | |
font-weight: 100; | |
font-size: 1.5rem; | |
} | |
.header { | |
position: relative; | |
flex: 1; | |
display: flex; | |
align-items: center; | |
} | |
.header svg { | |
--count: 4; | |
width: 106px; | |
} | |
.header svg:nth-of-type(2), | |
.header svg:nth-of-type(3), | |
.header svg:nth-of-type(4) { | |
position: absolute; | |
z-index: calc(var(--count) - var(--index)); | |
translate: calc(var(--index) * 30%) 0; | |
opacity: calc(var(--count) / (2 * (var(--index) * 10))); | |
} | |
.header svg:nth-of-type(2) { | |
--index: 1; | |
} | |
.header svg:nth-of-type(3) { | |
--index: 2; | |
} | |
.header svg:nth-of-type(4) { | |
--index: 3; | |
} | |
.badge svg { | |
width: 16px; | |
} | |
.dg.ac { | |
z-index: 99999 !important; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment