JSFiddle - React, Tailwind, and code Playground
by phloe
HTML
<main>
<h1>Front-end strategies</h1>
<output form="strategies">
<figure>
<svg viewBox="0 0 700 600" width="100%" height="100%">
<defs>
<mask id="mask_features">
<rect x="100" y="100" width="500" height="800" fill="#FFF" />
<rect x="100" y="100" width="500" height="400" fill="#404040" transform="translate(0 -100)" id="mask_features_active"/>
</mask>
<mask id="mask_polyfill">
<rect x="100" y="100" width="500" height="800" fill="#000" />
<rect x="100" y="100" width="500" height="400" fill="#404040" transform="translate(0 300)" id="mask_polyfill_active" />
</mask>
</defs>
<text x="100" y="90" text-anchor="start">Features</text>
<text x="600" y="520" text-anchor="end">Support</text>
<text x="610" y="110" text-anchor="start" fill="#E8742D" id="baseline_text">Baseline</text>
<text x="90" y="110" text-anchor="end" fill="#E8742D" id="polyfill_text">Polyfill</text>
<rect x="100" y="100" width="500" height="400" fill="#E8742D" mask="url(#mask_polyfill)" id="polyfill" />
<path d="M200,500 v-100 h100 v-100 h100 v-100 h100 v-100 h100 v400 z" fill="#333333" mask="url(#mask_features)" id="features" />
<path d="M100.5,100 v399.5 h499.5" stroke-width="1" stroke="#000" fill="transparent" id="axes" />
<path d="M100,499.5 h99.5 v-99 h100 v-100 h100 v-100 h100 v-100 h100" stroke-width="1" stroke="#E8742D" fill="transparent" id="baseline" />
</svg>
<figcpation>
</figcpation>
</figure>
</output>
<form id="strategies"></form>
</main>
SCSS
html {
font-family: -apple-system,".SFNSText-Regular","San Francisco","Roboto","Segoe UI","Helvetica Neue","Lucida Grande", sans-serif;
}
main {
max-width: 700px;
margin: 40px auto;
padding: 0 20px;
}
h1 {
text-transform: uppercase;
font-weight: bold;
text-align: center;
font-size: 42px;
@media (max-width: 720px) {
font-size: calc((42/720) * 100vw);
}
}
figure {
margin: 0;
}
svg text {
text-transform: uppercase;
font-size: 14px;
}
form {
padding: 0 100px;
@media (max-width: 720px) {
padding: 0 calc((100/720) * 100vw);
}
}
label span {
text-transform: uppercase;
display: block;
font-size: 14px;
@media (max-width: 720px) {
font-size: calc((14/720) * 100vw);
}
}
label input[type="range"] {
width: 100%;
}
label input + span {
display: inline;
}
#mask_polyfill_active,
#mask_features_active,
#baseline_text,
#polyfill_text {
_transition: .1s transform ease-in-out;
}
JavaScript
var levels = 4;
function updateGraph (baseValue, polyValue) {
mask_features_active.setAttribute("transform", `translate(0 -${baseValue * 100})`);
mask_polyfill_active.setAttribute("transform", `translate(0 ${(levels - polyValue) * 100})`);
baseline_text.setAttribute("transform", `translate(0 ${((levels - baseValue) / levels) * (levels * 100 - 10) })`);
polyfill_text.setAttribute("transform", `translate(0 ${((levels - polyValue) / levels) * (levels * 100 - 10) })`);
baseline.setAttribute("d", `
M100,${(levels - polyValue) * 100 + 100 - (polyValue ? 0 : 0.5)}
h${(polyValue + 1 ) * 100 + (baseValue < levels ? 0.5 : 0)}
${ "v-100 h100 ".repeat(baseValue - polyValue) }
${ (baseValue < levels) ? `h${ (levels - baseValue) * 100 }` : "" }
`);
}
var inputs = {
baseline: { value: 2, min: 0, max: levels, step: 1, rel: { key: "polyfill", type: "max" } },
polyfill: { value: 0, min: 0, max: levels, step: 1, rel: { key: "baseline", type: "min" } }
};
var form = document.querySelector("form");
Object.keys(inputs).forEach(function (key) {
var data = inputs[key];
var label = document.createElement("label");
var span = document.createElement("span");
span.textContent = `${key[0].toUpperCase()}${key.slice(1)}: `;
var input = document.createElement("input");
input.value = data.value;
input.min = data.min;
input.max = data.max;
input.step = data.step;
input.type = "range";
input.oninput = inputUpdate;
data.input = input;
function inputUpdate (event) {
var value = parseFloat(input.value, 10);
if (data.value !== value) {
data.value = value;
const {
rel: {
key: relKey, type
} = {}
} = data;
if (relKey) {
var rel = inputs[relKey];
var relVal = rel.value;
if (type === "min") {
relVal = Math.max(value, relVal);
}
else if (type === "max") {
relVal = Math.min(value, relVal);
}
if (relVal !== rel.value) {
rel.value = relVal;
rel.input.value = relVal;
}
}
if (event)...