Font Size Scaling Fix

User
var maxDist;
var mouse = { x: 0, y: 0 };
var cursor = {
x: window.innerWidth,
y: window.innerHeight
};

Math.dist = function(a, b) {
var dx = b.x – a.x;
var dy = b.y – a.y;
return Math.sqrt(dx * dx + dy * dy);
}

window.addEventListener("mousemove", function(e) {
cursor.x = e.clientX;
cursor.y = e.clientY;
});

window.addEventListener("touchmove", function(e) {
var t = e.touches[0];
cursor.x = t.clientX;
cursor.y = t.clientY;
}, {
passive: false
});

var Char = function(container, char) {
var span = document.createElement("span");
span.setAttribute('data-char', char);
span.innerText = char;
container.appendChild(span);
this.getDist = function() {
this.pos = span.getBoundingClientRect();
return Math.dist(mouse, {
x: this.pos.x + (this.pos.width / 1.75),
y: this.pos.y
});
}
this.getAttr = function(dist, min, max) {
var wght = max – Math.abs((max * dist / maxDist));
return Math.max(min, wght + min);
}
this.update = function(args) {
var dist = this.getDist();
this.wdth = args.wdth ? ~~this.getAttr(dist, 5, 200) : 100;
this.wght = args.wght ? ~~this.getAttr(dist, 100, 800) : 400;
this.alpha = args.alpha ? this.getAttr(dist, 0, 1).toFixed(2) : 1;
this.ital = args.ital ? this.getAttr(dist, 0, 1).toFixed(2) : 0;
this.draw();
}
this.draw = function() {
var style = "";
style += "opacity: " + this.alpha + ";";
style += "font-variation-settings: 'wght' " + this.wght + ", 'wdth' " + this.wdth + ", 'ital' " + this.ital + ";";
span.style = style;
}
return this;
}

var VFont = function(element) {
this.scale = false;
this.flex = true;
this.alpha = false;
this.stroke = false;
this.width = true;
this.weight = true;
this.italic = true;
var title = element;
var str = title.innerText;

var chars = [];

this.init = function() {
title.innerHTML = "";
for (var i = 0; i < str.length; i++) {
var _char = new Char(title, str[i]);
chars.push(_char);
}
this.set();
window.addEventListener("resize", this.setSize.bind(this));
}

this.set = function() {
title.className += this.flex ? " flex title variable-font-content " : "";
title.className += this.stroke ? " stroke" : "";
this.setSize();
}

this.setSize = function() {
var mainDiv = title.parentElement;

var fontSize = mainDiv.clientWidth / (str.length / 2);

title.style.fontSize = fontSize + "px";
if (this.scale) {
var scaleY = (window.innerHeight / title.getBoundingClientRect().height).toFixed(2);
var lineHeight = scaleY * 0.8;
title.style.transform = "scale(1," + scaleY + ")";
title.style.lineHeight = lineHeight + "em";
}
}

this.animate = function() {
mouse.x += (cursor.x – mouse.x) / 20;
mouse.y += (cursor.y – mouse.y) / 20;
requestAnimationFrame(this.animate.bind(this));
this.render();
}

this.render = function() {
maxDist = title.getBoundingClientRect().width / 2;
for (var i = 0; i < chars.length; i++) {
chars[i].update({
wght: this.weight,
wdth: this.width,
ital: this.italic,
alpha: this.alpha
});
}
}

this.init();
return this;
}

// Initialize for all elements with class "title"
var titles = document.querySelectorAll(".title");
var fontObjects = [];
titles.forEach(function(el) {
var txt = new VFont(el);
fontObjects.push(txt);
});

// Unified animation loop for all
function animateAll() {
mouse.x += (cursor.x – mouse.x) / 20;
mouse.y += (cursor.y – mouse.y) / 20;
requestAnimationFrame(animateAll);
fontObjects.forEach(function(font) {
font.render();
});
}
animateAll();
multiple elementor widget animation is working but not eact prev elementor widget title font size decreased i want title tobe same size

Assistant
You're experiencing a font size issue where the **previous Elementor widget title's font size decreases** when multiple widgets are animated using your `VFont` script. This happens because in your current code, the font size for each `.title` is calculated based on the container's width **divided by the number of characters**:

var fontSize = mainDiv.clientWidth / (str.length / 2);

This logic dynamically scales font size depending on how long the string is, causing inconsistencies across widgets — shorter titles will look bigger, and longer ones will look smaller.

### ✅ Solution: Normalize the font size across widgets

To fix this, **set a consistent font size** or make it responsive based on container width *only*, without factoring in string length.

#### 🔧 Option 1: Set a fixed font size
If you want all titles to have the same font size regardless of character count:

this.setSize = function() {
    var fixedFontSize = 48; // or any desired size in px
    title.style.fontSize = fixedFontSize + "px";

    if (this.scale) {
        var scaleY = (window.innerHeight / title.getBoundingClientRect().height).toFixed(2);
        var lineHeight = scaleY * 0.8;
        title.style.transform = "scale(1," + scaleY + ")";
        title.style.lineHeight = lineHeight + "em";
    }
}

#### 🔧 Option 2: Base font size on container width, not string length
This will scale based on container size but keep it consistent across different titles:

this.setSize = function() {
    var mainDiv = title.parentElement;
    var fontSize = mainDiv.clientWidth * 0.1; // adjust scaling factor as needed
    title.style.fontSize = fontSize + "px";

    if (this.scale) {
        var scaleY = (window.innerHeight / title.getBoundingClientRect().height).toFixed(2);
        var lineHeight = scaleY * 0.8;
        title.style.transform = "scale(1," + scaleY + ")";
        title.style.lineHeight = lineHeight + "em";
    }
}

Let me know if you want the font size to scale **based on viewport width**, **container size**, or just be **fixed**, and I can refine it more to match your design.

Assistant
Got it — you're using a `VFont` JavaScript animation to create responsive, variable font interactions with Elementor widgets, and you're initializing it for all elements with the class `.title`. However, when there are **multiple widgets**, the font size of **previous titles gets smaller**, and you want **all titles to maintain the same size** relative to their container.

### 🎯 Problem Source:
In your `VFont` function, this block calculates font size based on the parent width divided by the string length:

var fontSize = mainDiv.clientWidth / (str.length / 2);
title.style.fontSize = fontSize + "px";

This works well when used once. But when used for **multiple elements**, the parent container size (which can vary) and string length (which also varies) leads to inconsistent sizing across widgets.

### ✅ Solution:

Instead of calculating font size **based on string length**, use a **consistent logic** or a **fixed font size** based on a shared context (like the width of the widget container or a fixed value).

Here’s one clean solution:

#### 🔧 Fix in `this.setSize`:
Replace this line:

var fontSize = mainDiv.clientWidth / (str.length / 2);

With something consistent across all `.title` elements. For example:

var baseSize = 48; // or any desired px size
title.style.fontSize = baseSize + "px";

Or, to make it slightly dynamic but consistent:

var fontSize = mainDiv.clientWidth / 10; // adjust divisor for overall sizing
title.style.fontSize = fontSize + "px";

> ✅ The key is: **Don’t divide by string length**, because it varies across widgets.

### 🧪 Example Updated Code in Context:

this.setSize = function() {
    var mainDiv = title.parentElement;
    
    // Consistent font sizing logic for all titles
    var fontSize = mainDiv.clientWidth / 10; // consistent ratio
    title.style.fontSize = fontSize + "px";

    if (this.scale) {
        var scaleY = (window.innerHeight / title.getBoundingClientRect().height).toFixed(2);
        var lineHeight = scaleY * 0.8;
        title.style.transform = "scale(1," + scaleY + ")";
        title.style.lineHeight = lineHeight + "em";
    }
}

Let me know if you want to set the font size via CSS classes or Elementor controls instead — that could give you more editor flexibility too.

User
$this->add_group_control(
ElementorGroup_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '{{WRAPPER}} .variable-font-content',
]
);
HOw to get only font size
Assistant
To get only the **font size** from the `Group_Control_Typography` settings in Elementor, you can access it directly like this:

$settings = $this->get_settings_for_display();
$font_size = $settings['text_typography']['font_size'];

However, Elementor stores typography settings inside a nested array, so you need to extract it properly.

### ✅ Full Example:
If you're outputting the style manually in your widget render function:

$settings = $this->get_settings_for_display();

$font_size = !empty($settings['text_typography']['font_size']) ? $settings['text_typography']['font_size'] : '16px';

// Output with inline style, if needed
echo '<div class="variable-font-content" style="font-size: ' . esc_attr($font_size) . ';">Your Title</div>';

### ⚠️ Note:
– `font_size` may return either a **value only** (like `24`) or an array with **unit and value** depending on Elementor version.
– To be safer:

$font_size = '16px'; // default

if ( ! empty( $settings['text_typography']['font_size']['size'] ) && ! empty( $settings['text_typography']['font_size']['unit'] ) ) {
    $font_size = $settings['text_typography']['font_size']['size'] . $settings['text_typography']['font_size']['unit'];
}

Let me know if you're using this inside a “ block or want to pass this value to JavaScript as well!

User
Undefined array key "text_typography"
Assistant
Ah, gotcha! That `"Undefined array key 'text_typography'"` warning usually means Elementor has **flattened the settings**, especially with `Group_Control_Typography`. The font size isn’t inside a nested `'text_typography'` array—each property (like `font_size`, `font_weight`, etc.) is stored as an individual setting.

### ✅ Correct Way to Access Font Size:

Assuming you defined it like this:

$this->add_group_control(
    ElementorGroup_Control_Typography::get_type(),
    [
        'name'     => 'text_typography',
        'selector' => '{{WRAPPER}} .variable-font-content',
    ]
);

Then you can get just the font size like this:

$settings = $this->get_settings_for_display();

$font_size = isset($settings['text_typography_font_size']) ? $settings['text_typography_font_size'] : '16px';

If you also want to be safe about the unit:

$font_unit = isset($settings['text_typography_font_size_unit']) ? $settings['text_typography_font_size_unit'] : 'px';
$font_size_full = $font_size . $font_unit;

### 🧪 Example Usage:

echo '<div class="variable-font-content" style="font-size: ' . esc_attr($font_size_full) . ';">Your Title</div>';

Let me know if you're planning to send this font size to JavaScript too — I can show how to pass it through `data-` attributes or a script block.

Leave a Comment

Your email address will not be published. Required fields are marked *