JSFiddle - React, Tailwind, and code Playground
HTML
<h3>
Demo: Matching Halant metrics with <span style="color:red">Devanagari MT</span>.
</h3>
<h4>
Note: The two fonts can't perfectly match each other due to ligature differences. <br>
For example: <span style="font-family: Halant">उपलब्ध</span> vs. <span style="font-family: Devanagari MT; color: red">उपलब्ध</span>
</h4>
<div>
Font size: <input type=number value=16 id=fontSizeInput>
</div>
<div>
Width: <input type=number value=800 id=widthInput>
</div>
<div>
Animate <input type=checkbox id=animateCheck>
</div>
<div style="height: 20px"></div>
<div class=container>
<div class=reference></div>
<div class=target></div>
</div>
CSS
@import url('https://fonts.googleapis.com/css2?family=Halant&display=swap');
@font-face {
font-family: Devanagari MT;
/* Halant has ascent 1089, descent -486 and line gap 0
* in its hhea table. Units per em is 1000.
*/
ascent-override: calc(1089 / 1000 * 100%);
descent-override: calc(486 / 1000 * 100%);
line-gap-override: 0%;
advance-override: 89%;
src: local(Devanagari MT);
}
.container {
position: relative;
width: calc(var(--w) * 1px);
height: calc(500px * var(--f) * var(--f) / var(--w));
font-size: calc(var(--f) * 1px);
}
.reference {
font-family: Halant;
position: absolute;
}
.target {
font-family: Devanagari MT;
color: red;
position: absolute;
}
.hidden {
visibility: hidden;
}
JavaScript
const text = `वर्णन` + ` जिम्मे पुर्णता भाति पहोच। सारांश पासपाई उपयोगकर्ता देते. अत्यंत दुनिया बनाने मुखय किया संसाध तकनीकी वर्तमान आंतरकार्यक्षमता! भाषा उपलब्ध नयेलिए चिदंश. बनाने सेऔर पासपाई सोफ़्टवेर विस्तरणक्षमता. संपादक गुजरना पडता करता।. रखति अनुकूल ब्रौशर परिवहन हमारि करेसाथ अनुवाद मजबुत जिसे. प्राण दिये उपलब्ध विश्वास सुस्पश्ट प्रदान है।अभी मुश्किल सदस्य समूह. भाषाओ साधन उसीएक् व्याख्या. खरिदे पासपाई सुस्पश्ट संस्क्रुति करता! अंग्रेजी विचरविमर्श विशेष जाएन खयालात उपेक्ष दोषसके बिना विभाग. उद्योग विकसित क्षमता। रखति सादगि? सामूहिक भोगोलिक गटको जानते एवम् सीमित स्थिति सहायता सामूहिक.`
document.querySelectorAll('.reference').forEach(e => e.innerHTML = text);
document.querySelectorAll('.target').forEach(e => e.innerHTML = text);
function modify() {
const container = document.querySelector('.container');
container.setAttribute('style', `--w: ${widthInput.value}; --f: ${fontSizeInput.value}`)
}
widthInput.onchange = modify;
fontSizeInput.onchange = modify;
modify();
let intervalId;
function startAnimate() {
function toggle() {
document.querySelector('.reference').classList.toggle('hidden');
document.querySelector('.target').classList.toggle('hidden');
}
document.querySelector('.reference').classList.add('hidden');
intervalId = setInterval(toggle, 500);
}
function stopAnimate() {
clearInterval(intervalId);
document.querySelector('.reference').classList.remove('hidden');
document.querySelector('.target').classList.remove('hidden');
}
animateCheck.onchange = function() {
if (animateCheck.checked)
startAnimate();
else
stopAnimate();
}