我一直在尝试制作一个包含画布的响应式网站。
在绘制圆形进度条时,正在调用arc()
函数,但它radius
参数看起来需要以像素为单位,但我需要它作为百分比、vw、vh、em 或任何其他单位 css 建议。
当然,我可以以像素为单位渲染它并使用CSS拉伸它,但它要么被放大和像素化,要么被缩小并浪费资源,要么被扭曲。
我应该怎么做?
经过一番搜索,我偶然发现了这个问题,它帮助我解决了这个问题。
这是我是如何做到的:
var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
var vw = w/100;
var vh = h/100;
var pxradius = 50;
var vwradius = pxradius*vw;
不幸的是,我仍然没有百分比和 ems 的解决方案
我现在正在做一些事情,我必须解决完全相同的问题(即以百分比或 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;
}
为了戳一下,JSFiddle上有演示。
现在,一些解释/评论:emToPixelElementRelative
和percentToPixelElementRelative
分别转换作为第一个参数传递给它的值em=>px
和%=>px
。两个函数(element
)的第二个参数是一个元素,基于该元素将计算尺寸,px
中的值(注意:请记住,您将半径而不是直径传递给arc()
,对于百分比意味着如果您传递50(%)并将基于canvas
元素进行计算 - 圆的直径将是100%,并将填充整个canvas
(在方形画布的情况下)),如果未传递参数 — 根据视口的尺寸计算值。第三个参数(width_based
)反映计算的值是相对于宽度(如果设置为默认值设置为true
)还是相对于高度(如果设置为false
)。
percentToPixelParentBased
和emToPixelParentBased
只是percentToPixelElementRelative
和emToPixelElementRelative
的包装器,它们基于传递element
的父级进行转换。
getFontSize
返回传递element
的字体大小,或者<body>
元素(如果不带参数调用)的字体大小。
getPPI
通过本答案中提到的黑客获得当前的 PPI,它接受单个参数 (width_based
) 指示是否将其计算基于宽度(如果true
- 默认值)或高度(如果false
)。
另请注意,我基于以下假设进行em=>px
计算:
- 字体大小以
pt
为单位(基于本文) 1em
等于pt
当前字体的大小(基于 pxtoem.com 和这个答案)- 转换
pt=>px
的公式1pt = 72 / ppi
(基于此答案)
问题(当然还有答案)/资源,帮助我将这个解决方案放在一起:
- 获取当前 PPI:
- 如何按 id 删除 HTML 元素
- 如何将元素插入到 HTML 中
- 如何获得当前 PPI 的一般配方
- 获取当前字体大小:
- 如何获取当前字体大小
- 获取 HTML 元素(MDN 星期三文档)
- 像素转换百分比:
- 当然,基于Magix上面的回答
- 电磁到像素的转换:
- 什么是电磁 (PXtoEM.com)
- 如何计算 EM
- 如何将 pt 转换为 px
- 杂项:
- 使用 PXtoEM.com 链接回答 偏移宽度、
- 客户端宽度、滚动宽度和高度之间的差异
- 如何在堆栈溢出标记中制作嵌套列表 =)