Вот решение с использованием автономной версии fittext. js.
Я добавил небольшой javascript код, выполняемый при обходе «Загрузка документа» массив querySelectorAll
элементов для класса .fittext
.
Параметры для 'fitText': элемент, компрессор и размер шрифта {min, max}. После того, как мы поработали с параметрами, это, кажется, дает хороший результат: window.fitText(elem, 1.2, { min: '14px', max: '60px' })
Мой код javascipt в конце. Обратите внимание на код CSS «адаптивного размера» html {font-size: calc(0.625vmin + 0.75rem)}
и .quizItemAnswerText { width; height}
, оба calc(9vmin + 127.2px)
, все с использованием уравнения y = mx + b , «определение прямой линии».
Обязательно проверяйте комментарии в CSS.
Теперь вы добавляете код JS для квадрата внутри круга ....
Промежуточное обновление (2)
Оригинальный 'fittext. js' использует JS clientWidth
, включая отступы. Добавлена опция (и код), чтобы выбрать, удалять ли отступы от clientWidth
Для корректной работы «отзывчивого заполнения» необходимо удалить отступы.
Готово:
- Проверьте, подходит ли текст, и ничего не делайте. Оригинальный код действительно игнорирует это, что я считаю недостатком (или упущением).
Теперь «fitText» оставит font-size
как есть, когда текст помещается в элемент. Осталось немного кода отладки, пропадет следующее обновление ...
Еще предстоит сделать:
- создать CSS cal c () для «отзывчивого заполнения» ( y = mx + b, настроенный с помощью Пифагора, это может занять некоторое время, чтобы выяснить ...)
'use-strict';
const crlf = '\r\n';
const br = '<br>';
// Standalone versions of 'getTextWidth' and 'getDimensions'
// for debugging or use elsewhere
function getTextWidth(txt, fontname, fontsize){
var c=document.createElement('canvas'); // Create a dummy canvas (render invisible with css)
var ctx=c.getContext('2d'); // Get the context of the dummy canvas
ctx.font = fontsize + ' ' + fontname; // Set the context.font to the 'actual' font
var width = ctx.measureText(txt).width; // Measure the string
c.remove(); // No loose ends...
return Math.ceil(width); // Return rounded up width
};
function getDimensions(element) {
var cmp = getComputedStyle(element);
// get dimenision including padding
var width = element.clientWidth;
var height = element.clientHeight;
// convert strings (+'px') to float
var t = parseFloat(cmp.paddingTop);
var r = parseFloat(cmp.paddingRight);
var b = parseFloat(cmp.paddingBottom);
var l = parseFloat(cmp.paddingLeft);
// Remove padding
width -= r + l;
height -= t + b;
// Wit hand height (include padding for easy "already converted" access)
return { width: width, height: height, padding: { top: t, right: r, bottom: b, left: l } };
};
/*!
* FitText.js 1.01 jQuery free version
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
* Modified by Slawomir Kolodziej http://slawekk.info
*
* v1.01 by Rene van der Lende, March 2020
* - added 'getTextWidth' and 'getDimensions'
* - extra boolean parameter to select
* (default) with padding
* (optional) without padding
*/
(function(){
var addEvent = function (el, type, fn) {
if (el.addEventListener)
el.addEventListener(type, fn, false);
else
el.attachEvent('on'+type, fn);
};
var extend = function(obj,ext){
for(var key in ext)
if(ext.hasOwnProperty(key))
obj[key] = ext[key];
return obj;
};
window.fitText = function (el, kompressor, options, incpad) {
var settings = extend({
'minFontSize' : -1/0,
'maxFontSize' : 1/0
},options);
// start RvdL, March 2020
var getDimensions = function (el) {
var cmp = getComputedStyle(el);
// get dimenision including padding
var width = el.clientWidth;
var height = el.clientHeight;
// convert strings (+'px') to float
var t = parseFloat(cmp.paddingTop);
var r = parseFloat(cmp.paddingRight);
var b = parseFloat(cmp.paddingBottom);
var l = parseFloat(cmp.paddingLeft);
// Remove padding
width -= r + l;
height -= t + b;
// width and height (include padding for easy "already converted" access)
// height and padding redudant in `fitText`, but who knows...
return { width: width, height: height, padding: { top: t, right: r, bottom: b, left: l } };
};
function getTextWidth(el) {
var c = document.createElement('canvas'); // Create a dummy canvas (render invisible with css)
var ctx = c.getContext('2d'); // Get the context of the dummy canvas
ctx.font = getComputedStyle(el).fontSize + ' sans-serif';
// TODO: Flawed because using fixed 'sans-serif'
// Use only first node of element (the text) as 'innerText' may contain child elements
var width = ctx.measureText(el.childNodes[0].nodeValue).width;
c.remove(); // No loose ends...
return Math.ceil(width); // Return rounded up width
};
// end RvdL, March 2020
var fit = function (el) {
var compressor = kompressor || 1; // if null default to 1
var padded = (incpad=null) || incpad; // if null then 'old behaviour' with padding
var resizer = function () { // include/exclude padding
var elWidth = (padded) ? el.clientWidth : getDimensions(el).width;
if ( elWidth < getTextWidth(el) ) { // Skip when text fits already
el.style.fontSize = Math.max(Math.min(elWidth / (compressor*10),
parseFloat(settings.maxFontSize)),
parseFloat(settings.minFontSize)) + 'px';
};
};
// Call once to set.
resizer();
// Bind events
// If you have any js library which support Events, replace this part
// and remove addEvent function (or use original jQuery version)
addEvent(window, 'resize', resizer);
addEvent(window, 'orientationchange', resizer);
};
if (el.length)
for(var i=0; i<el.length; i++)
fit(el[i]);
else
fit(el);
// return set of elements
return el;
};
})();
/******************************************************/
window.addEventListener('load', initialize); // Do when all HTML/CSS has been loaded
/******************************************************/
var forEachEntryIn = function (array, callback, scope) {
for (var i = 0; i < array.length; i++) { callback.call(scope, i, array[i]); } };
function initialize() {
var cmp;
forEachEntryIn(document.querySelectorAll('.fittext'),
function (idx,elem,scope) {
cmp = window.getComputedStyle(elem); // debug
// Original font size
console.log('canvas', getTextWidth(elem.childNodes[0].nodeValue, 'sans-serif', cmp.fontSize),
'fs' , cmp.fontSize);
// Params: element, compressor, min/max font-size, strip padding from width
window.fitText(elem, 1.2, { min: '14px', max: '60px'}, false );
// fitText font size
console.log('canvas', getTextWidth(elem.childNodes[0].nodeValue, 'sans-serif', window.getComputedStyle(elem).fontSize),
'fs' , window.getComputedStyle(elem).fontSize);
});
};
/*
made responsive y=mx+b
points p1(320,14) p2(1280,20)
*/
html { font-size: calc(0.625vmin + 0.75rem) }
.quizItemAnswerText {
display: flex;
justify-content: center;
align-items: center;
/*
made responsive y=mx+b
points p1(320,156) p2(1920,300)
*/
height: calc(9vmin + 127.2px);
width : calc(9vmin + 127.2px);
padding: 15px;
margin: 5px 60px;
margin-bottom:200px;
font-family: 'News Gothic Std',arial,sans-serif;
font-weight: bold;
/*
made responsive y=mx+b
points p1(320,24) p2(1280,60)
*/
font-size: calc(3.75vmin + 0.75rem); /* modified from 60px */
text-align: center;
border-radius: 50%; /* adjusted from 100% */
border: 3px solid black;
background: #333;
color:#72B74D;
}
<div data-answervalidation="false" data-answerindex="3" class="fittext quizItemAnswerClick quizItemAnswerText">Proin ac libero sit amet metus semper aliquet. Proin ut tellus ut nulla pharetra</div>
<div data-answervalidation="false" data-answerindex="3" class="fittext quizItemAnswerClick quizItemAnswerText">TRUE</div>