我现在正在做一些事情,我必须解决完全相同的问题(即以百分比或 ems 为 CanvasRenderingContext2D.arc() 设置半径值)。
这是我的解决方案的 JavaScript 代码:
function percentToPixelParentBased(percent, element, width_based=true) {
return percentToPixelElementRelative(percent, element.parentElement, width_based);
}
function emToPixelParentBased(em_value, element) {
return emToPixelElementRelative(em_value, element.parentElement);
}
function percentToPixelElementRelative(percent, element=false, width_based=true) {
if (element) {
if (width_based) {
var dimension = element.style.width || element.offsetWidth;
} else {
var dimension = element.style.height || element.offsetHeight;
}
} else {
if (width_based) {
var dimension = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
} else {
var dimension = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}
}
var pixels_in_percent = dimension / 100;
return pixels_in_percent * percent;
}
function emToPixelElementRelative(em_value, element=false) {
var font_size = getFontSize(element);
var ppi = getPPI();
var px_in_pt = 72 / ppi; /* 1pt is 1/72 of an inch */
var value_in_pt = em_value * font_size;
return value_in_pt * px_in_pt;
}
function getFontSize(element=false) {
if (element) {
return parseFloat(getComputedStyle(element).fontSize);
} else {
/* getting font size from body */
return parseFloat(getComputedStyle(document.body).fontSize);
}
}
function getPPI() {
var inch_div_html = "<div id='inch-div' style='height: 1in; left: -100%; position: absolute; top: -100%; width: 1in;'></div>";
document.body.insertAdjacentHTML( 'afterbegin', inch_div_html);
var device_pixel_ratio = window.devicePixelRatio || 1;
var ppi_test_div = document.getElementById('inch-div');
var ppi = ppi_test_div.offsetWidth * devicePixelRatio;
document.body.removeChild(ppi_test_div);
return ppi;
}
稍微戳一下,有demo on JSFiddle。
现在,一些解释/备注:emToPixelElementRelative 和 percentToPixelElementRelative 分别转换作为第一个参数 em=>px 和 %=>px 传递给它的值。两个函数的第二个参数 (element) 是一个元素,基于哪些尺寸,px 中的值将被计算 (注意:请记住,您将半径而不是直径传递给 arc(),它for percents 表示如果您通过 50(%) 并将基于 canvas 元素进行计算 - 圆的直径将为 100% 并将填充整个 canvas(在方形画布的情况下)) em>,如果未传递参数 - 根据视口的尺寸计算值。第三个参数 (width_based) 反映计算的值是相对于宽度(如果设置为 true,这是默认值)还是高度(如果设置为 false)。
percentToPixelParentBased 和 emToPixelParentBased 只是 percentToPixelElementRelative 和 emToPixelElementRelative 的包装器,它们基于传递的 element 的父级进行转换。
getFontSize 返回传递的element 或<body> 元素的字体大小(如果调用时不带参数)。
getPPI 正在通过 hack mentioned in this answer 获取当前 PPI,它接受单个参数 (width_based) 指示是否基于宽度(如果 true - 默认)或高度(如果 @ 987654366@).
另外请注意,我的 em=>px 计算基于以下假设:
问题(当然还有对它们的答案)/资源,它们帮助我把这个解决方案放在一起:
- 获取当前 PPI:
- 获取当前字体大小:
- 像素转换百分比:
- Em 到像素的转换:
- 杂项: