【问题标题】:2D Canvas : specify `arc()` radius units2D 画布:指定 `arc()` 半径单位
【发布时间】:2017-10-10 21:50:43
【问题描述】:

我一直在尝试制作一个包含画布的响应式网站。

在绘制圆形进度条时,正在调用 arc() 函数,但它的 radius 参数看起来需要以像素为单位,但我需要它为百分比、vw、vh、em 或任何其他单元 css 建议。

当然,我可以将其渲染为像素并使用 CSS 进行拉伸,但它要么被放大和像素化,要么被缩小并浪费资源,要么被扭曲。

我应该怎么做?

【问题讨论】:

    标签: javascript css canvas responsive-design units-of-measurement


    【解决方案1】:

    经过一番搜索,我偶然发现了this question,它帮助我解决了问题。

    我是这样做的:

    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 的方法

    【讨论】:

    • 在我看来,您的代码准确地将pxradius 的百分比值转换为像素值。所以它是百分比的解决方案。我错过了什么吗?
    • 嗯,不是真的,因为百分比是相对于放置元素的容器(afaik)而这里它只是相对于窗口的高度/宽度
    【解决方案2】:

    我现在正在做一些事情,我必须解决完全相同的问题(即以百分比或 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


    现在,一些解释/备注:emToPixelElementRelativepercentToPixelElementRelative 分别转换作为第一个参数 em=&gt;px%=&gt;px 传递给它的值。两个函数的第二个参数 (element) 是一个元素,基于哪些尺寸,px 中的值将被计算 (注意:请记住,您将半径而不是直径传递给 arc(),它for percents 表示如果您通过 50(%) 并将基于 canvas 元素进行计算 - 圆的直径将为 100% 并将填充整个 canvas(在方形画布的情况下)) em>,如果未传递参数 - 根据视口的尺寸计算值。第三个参数 (width_based) 反映计算的值是相对于宽度(如果设置为 true,这是默认值)还是高度(如果设置为 false)。

    percentToPixelParentBasedemToPixelParentBased 只是 percentToPixelElementRelativeemToPixelElementRelative 的包装器,它们基于传递的 element 的父级进行转换。

    getFontSize 返回传递的element&lt;body&gt; 元素的字体大小(如果调用时不带参数)。

    getPPI 正在通过 hack mentioned in this answer 获取当前 PPI,它接受单个参数 (width_based) 指示是否基于宽度(如果 true - 默认)或高度(如果 @ 987654366@).

    另外请注意,我的 em=&gt;px 计算基于以下假设:


    问题(当然还有对它们的答案)/资源,它们帮助我把这个解决方案放在一起:

    1. 获取当前 PPI:
    2. 获取当前字体大小:
    3. 像素转换百分比:
    4. Em 到像素的转换:
    5. 杂项:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多