<div mv-app="rangeMapping" mv-mode="edit">
<p>Our variable is <code>--<span property="variableName">p</span></code>.
<p>When <code>--[variableName]</code> is <code property="min_x">-1</code>, we want to output <code property="min_y">.2em</code>.
<p>When <code>--[variableName]</code> is <code property="max_x">1</code>, we want to output <code property="max_y">.8em</code>.
<p>The expression we need is <input class="mv-autosize" id="calcOutput" value="calc([a] * var(--[variableName]) + [b])" readonly></p>
<footer>
<details>
<summary>Debug info</summary>
a_raw = <span property="a_raw">([max_y] - [min_y]) / ([max_x] - [min_x])</span><br>
a = <span property="a">[simplifyExpression(a_raw)]</span><br>
b_raw = <span property="b_raw">[min_y] - [a] * [min_x]</span><br>
b = <span property="b">[simplifyExpression(b_raw)]</span>
</details>
• Made by <a href="https://lea.verou.me">Lea Verou</a> with <a href="https://mavo.io">Mavo</a>
</footer>
</div>
body {
margin: 0;
min-height: 100vh;
font: 200%/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
padding: 1em;
}
input {
font: inherit;
}
code, #calcOutput {
font-family: Consolas, Monaco, monospace;
background: hsl(220 10% 95%);
padding: .2em .3em;
border-radius: .2em;
border: none;
}
footer {
font-size: 50%;
opacity: .5;
}
footer details:not([open]) {
display: inline;
}
let dummy = document.createElement("div");
let properties = [
"width",
"flex-grow",
"rotate"
];
function simplifyExpression(expr) {
let value = `calc(${expr})`;
let property;
for (let prop of properties) {
if (CSS.supports(prop, value)) {
property = prop;
break;
}
}
if (property) {
dummy.style = "";
dummy.style[property] = value;
ret = dummy.style[property];
ret = ret.replace(/^calc/, "");
if (!/ \+ | - |\*|\//.test(ret)) {
ret = ret.replace(/^\(|\)$/g, "");
}
return ret;
}
return expr;
}
document.addEventListener("mv-change", evt => {
Stretchy.resize(calcOutput);
});
calcOutput.onfocus = function(evt) {
this.select();
};