<div class="app">
<div class="cursor"></div>
<div class="sample">Consider the following</div>
<dl class="output">
<div>
<dt><abbr title="weight">wght</abbr></dt>
<dd id="wght-out">400</dd>
</div>
<div>
<dt><abbr title="slant">slnt</abbr></dt>
<dd id="slnt-out">0</dd>
</div>
</dl>
</div>
@import url("https://fonts.googleapis.com/css2?family=Afacad+Flux:slnt,wght@-14..14,100..1000&display=swap");
$font-sans: "Afacad Flux", serif;
$ui: #eee;
$ui-dark: #777;
body {
font-family: $font-sans;
min-height: 100vh;
display: grid;
place-items: center;
font-variation-settings: "slnt" 0;
overflow: hidden;
}
.app {
display: grid;
place-content: center;
position: relative;
width: 100%;
background-image: linear-gradient(
to right,
transparent 50%,
$ui 50%,
$ui calc(50% + 1px),
transparent calc(50% + 1px)
),
linear-gradient(
to bottom,
transparent 50%,
$ui 50%,
$ui calc(50% + 1px),
transparent calc(50% + 1px)
);
max-width: 100vmin;
max-height: 100vmin;
aspect-ratio: 4 / 3;
border: 1px solid $ui;
cursor: none;
text-align: center;
line-height: 0.9;
}
.cursor {
width: 3px;
aspect-ratio: 1;
border-radius: 100%;
background-color: $ui-dark;
position: absolute;
top: 0;
left: 0;
transform: translateX(calc(var(--cursor-x, 0) - 1.5px))
translateY(calc(var(--cursor-y, 0) - 1.5px));
}
.sample {
font-size: 3.5em;
font-variation-settings: "wght" clamp(100, var(--wght), 1000),
"slnt" clamp(-14, var(--slnt), 14);
}
dl {
position: absolute;
bottom: 0;
left: 0;
font-size: 0.75rem;
display: flex;
color: $ui-dark;
}
dd {
min-width: 7ch;
font-variant-numeric: tabular-nums;
}
View Compiled
console.clear();
const mapRange = (value, oldMin, oldMax, newMin, newMax) =>((value - oldMin) / (oldMax - oldMin)) * (newMax - newMin) + newMin;
const clamp = (min, n, max) => {
return Math.min(Math.max(n, min), max);
};
const app = document.querySelector('.app');
const cursor = app.querySelector('.cursor');
const wghtOut = app.querySelector('#wght-out');
const slntOut = app.querySelector('#slnt-out');
let {width: appWidth, height: appHeight, left: appOffsetLeft, top: appOffsetTop} = app.getBoundingClientRect();
app.style.setProperty('--max-x', `${appWidth}px`);
app.style.setProperty('--max-y', `${appHeight}px`);
window.addEventListener('mousemove', ({clientX, clientY}) => {
const normalX = clamp(0, clientX - appOffsetLeft, appWidth);
const normalY = clamp(0, clientY - appOffsetTop, appHeight);
const computedSlnt = mapRange(normalX / appWidth, 0, 1, 14, -14)
const computedWght = mapRange(normalY / appHeight, 0, 1, 100, 1000)
app.style.setProperty('--cursor-x', `${normalX}px`)
app.style.setProperty('--cursor-y', `${normalY}px`)
app.style.setProperty('--slnt', clamp(-14, computedSlnt, 14));
app.style.setProperty('--wght', clamp(100, computedWght, 1000));
slntOut.textContent = clamp(-14, computedSlnt.toFixed(2), 14);
wghtOut.textContent = clamp(100, computedWght.toFixed(2), 1000);
})
window.addEventListener('resize', () => {
const rect = app.getBoundingClientRect();
appWidth = rect.width;
appHeight = rect.height;
appOffsetLeft = rect.left;
appOffsetTop = rect.top;
app.style.setProperty('--max-x', `${appWidth}px`);
app.style.setProperty('--max-y', `${appHeight}px`);
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.