进度圆 - 在圆的末端画一个小圆弧 + 更多 [英] Progress circle - draw a small arc at the end tip of the circle + more

查看:31
本文介绍了进度圆 - 在圆的末端画一个小圆弧 + 更多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在进度圆的末端画一个小圆,并在其下方/上方添加一个小文本块?

示例 img:

<div class="circle"><div class="img"></div><div class="mask full"><div class="fill"></div>

<div class="mask half"><div class="fill"></div><div class="fill fix"></div>

<div class="shadow"></div>

<div class="inset"><div class="百分比"><div class="numbers"><span>-</span><span>0%</span><span>1%</span><!---很多跨度--->

感谢 Andre 的 medium.com 文章,我已经对他的版本进行了一些编辑 - 更新版本说明了我想要为给定的 % 值动态实现的目标:http://codepen.io/Inlesco/pen/pgKXeG

然而,编译的CSS太多了.对于 100 中的每一 %,将有太多的 CSS 来定位事物.当前的 CSS(@codepen 示例)的权重已经约为 50 KB.不是最佳做法.

我已经在基于 JS Canvas 的变体上取得了一些进展,将 vert&horz 居中的 img 定位在画布上方.但这真的是一个好看的响应式网站的唯一途径和最佳实践吗?

解决方案

CSS 绝对不是执行此操作的正确工具,我建议您放弃这个想法.Canvas 绝对是一个不错的选择,但对于响应式网站,我建议您使用 SVG.使用 SVG,可以根据用户输入轻松绘制进度圆,并在其尖端添加圆/点.

以下是首先创建进度圈必须执行的步骤:

要在其尖端添加点/圆,需要执行以下操作:

文本也可以使用 text 元素添加,然后可以使用 xy 属性设置其位置.(这一点仍然需要在下面的代码片段中进行调整.)

演示:

下面是一个非常粗略的实现演示.

window.onload = function() {var btn = document.querySelector('button'),inp = document.querySelector('#progress'),path = document.querySelector('#p'),text = document.querySelector('#val'),rect = document.querySelector('rect'),output = document.querySelector('#path-output');变量 x = 0,y = 0,r = 30,CX = 50,cy = 50,d = '',填充 = '黄绿色',中风 = '透明';btn.addEventListener('click', function() {进度 = (inp.value == '') ?0 : inp.value;arcRad = ((progress * 360/100) - 90) * Math.PI/180;x = Math.cos(arcRad) * r + cx;y = Math.sin(arcRad) * r + cy;如果(进度 > 0 && 进度 <= 50){d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;设置颜色(填充,描边);设置输出();} else if (progress > 50 && progress <= 100) {d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + cx + ',' + (cy + r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;设置颜色(填充,描边);设置输出();} 别的 {text.innerHTML = '';path.setAttribute('d', '');output.innerHTML = '输入一个 0 到 100 之间的值';setColors('透明', '透明');}如果(进度 > 0 && 进度 <= 10){rect.setAttribute('x', x);rect.setAttribute('y', y + 7.5);text.setAttribute('x', x + 2);text.setAttribute('y', y + 15);} else if (progress > 10 && progress <= 62) {rect.setAttribute('x', x - 5);rect.setAttribute('y', y + 7.5);text.setAttribute('x', x - 3.5);text.setAttribute('y', y + 15);} else if (progress > 62 && progress <= 100) {rect.setAttribute('x', x - 5);rect.setAttribute('y', y - 15);text.setAttribute('x', x - 3.5);text.setAttribute('y', y - 7.5);}});函数 setColors(填充,描边){rect.setAttribute('填充', 填充);rect.setAttribute('stroke',stroke);path.setAttribute('填充', 填充);path.setAttribute('stroke',stroke);}函数集输出(){path.setAttribute('d', d);text.innerHTML = 进度;output.innerHTML = '以弧度表示的角度:' + arcRad + '<br/>';output.innerHTML += '圆中点:' + x + ',' + y + '<br/>';output.innerHTML += '路径 d 属性:' + d;}}

svg {宽度:200px;高度:200px;}.输出 {最小高度:20px;}h4{边框底部:1px 实心;}

<button>生成</button><br/><svg viewBox='0 0 100 100'><定义><marker id='dot' viewBox='0 0 10 10' markerHeight='10' markerWidth='10' refX='5' refY='5'><circle cx='5' cy='5' r='2'/></标记></defs><path d=''marker-end='url(#dot)' id='p'stroke='transparent' fill='transparent'/><rect height='10' width='10' x='10' y='10'stroke='transparent' fill='transparent'/><text x='10' y='10' id='val' font-family='Arial' font-size='6'></text></svg><div class='output'><h4>输出:</h4><output id='path-output'></output>

进一步阅读:

您可以在以下链接中阅读有关 SVG、其元素和属性的更多信息:

SVG 路径 |标记元素 |文本元素 |圆形元素

How do I draw a small circle at the end tip of a progress circle, plus adding a small text block below / above it?

Example img:

<div class="radial-progress" data-progress="0">
    <div class="circle">
    <div class="img"></div>
        <div class="mask full">
            <div class="fill"></div>
        </div>
        <div class="mask half">
            <div class="fill"></div>
            <div class="fill fix"></div>
        </div>
        <div class="shadow"></div>
    </div>
    <div class="inset">
        <div class="percentage">
            <div class="numbers"><span>-</span><span>0%</span><span>1%</span> <!--- lots of spans --->
        </div>
    </div>
</div>

Thanks to Andre's medium.com article, I've already edited his version a little - an UPDATED version illustrates what I want to achieve dynamically for a given % value: http://codepen.io/Inlesco/pen/pgKXeG

However, the compiled CSS is way too much. For each % out of 100, there'll be too much CSS for positioning things. The current CSS (@codepen example) already weights ~50 KB. Not the best practice.

I've already done some progress on a JS Canvas-based variant of this, positioning the vert&horz centered img above the canvas. But is it really the only way and best practice for a good-looking responsive website?

解决方案

CSS is definitely not the right tool for doing this and I would urge you to give up on that idea. Canvas is definitely a good option but for a responsive website, I would recommend you to use SVG. With SVG, it is easy to draw the progress circle based on user input and also add the circle/dot at the tip of it.

The following are the steps that would have to be performed to first create the progress circle:

For adding the dot/circle at its tip, the following need to be done:

Text can also be added using the text element and then its position can be set using the x and y attributes. (This bit still needs tuning in the below snippet.)

Demo:

Below is a very rough demo of the implementation.

window.onload = function() {
  var btn = document.querySelector('button'),
    inp = document.querySelector('#progress'),
    path = document.querySelector('#p'),
    text = document.querySelector('#val'),
    rect = document.querySelector('rect'),
    output = document.querySelector('#path-output');
  var x = 0,
    y = 0,
    r = 30,
    cx = 50,
    cy = 50,
    d = '',
    fill = 'yellowgreen',
    stroke = 'transparent';
  btn.addEventListener('click', function() {
    progress = (inp.value == '') ? 0 : inp.value;
    arcRad = ((progress * 360 / 100) - 90) * Math.PI / 180;

    x = Math.cos(arcRad) * r + cx;
    y = Math.sin(arcRad) * r + cy;

    if (progress > 0 && progress <= 50) {
      d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;
      setColors(fill, stroke);
      setOutput();
    } else if (progress > 50 && progress <= 100) {
      d = 'M' + x + ',' + y + ' L' + cx + ',' + cy + ' L' + cx + ',' + (cy - r) + ' A' + r + ',' + r + ' 0 0,1' + cx + ',' + (cy + r) + ' A' + r + ',' + r + ' 0 0,1' + x + ',' + y;
      setColors(fill, stroke);
      setOutput();
    } else {
      text.innerHTML = '';
      path.setAttribute('d', '');
      output.innerHTML = 'Enter a value between 0 and 100';
      setColors('transparent', 'transparent');
    }

    if (progress > 0 && progress <= 10) {
      rect.setAttribute('x', x);
      rect.setAttribute('y', y + 7.5);
      text.setAttribute('x', x + 2);
      text.setAttribute('y', y + 15);
    } else if (progress > 10 && progress <= 62) {
      rect.setAttribute('x', x - 5);
      rect.setAttribute('y', y + 7.5);
      text.setAttribute('x', x - 3.5);
      text.setAttribute('y', y + 15);
    } else if (progress > 62 && progress <= 100) {
      rect.setAttribute('x', x - 5);
      rect.setAttribute('y', y - 15);
      text.setAttribute('x', x - 3.5);
      text.setAttribute('y', y - 7.5);
    }

  });

  function setColors(fill, stroke) {
    rect.setAttribute('fill', fill);
    rect.setAttribute('stroke', stroke);
    path.setAttribute('fill', fill);
    path.setAttribute('stroke', stroke);
  }

  function setOutput() {
    path.setAttribute('d', d);
    text.innerHTML = progress;
    output.innerHTML = 'Angle in Radians: ' + arcRad + '<br/>';
    output.innerHTML += 'Point in Circle: ' + x + ',' + y + '<br/>';
    output.innerHTML += 'Path d attribute: ' + d;
  }
}

svg {
  width: 200px;
  height: 200px;
}
.output {
  min-height: 20px;
}
h4 {
  border-bottom: 1px solid;
}

<input id='progress' type='number' />
<button>Generate</button>
<br/>
<svg viewBox='0 0 100 100'>
  <defs>
    <marker id='dot' viewBox='0 0 10 10' markerHeight='10' markerWidth='10' refX='5' refY='5'>
      <circle cx='5' cy='5' r='2' />
    </marker>
  </defs>
  <path d='' marker-end='url(#dot)' id='p' stroke='transparent' fill='transparent' />
  <rect height='10' width='10' x='10' y='10' stroke='transparent' fill='transparent' />
  <text x='10' y='10' id='val' font-family='Arial' font-size='6'></text>
</svg>
<div class='output'>
  <h4>Output:</h4>
  <output id='path-output'></output>
</div>

Further Reading:

You can read more about SVG, its elements and attributes in the following links:

SVG Paths | Marker element | Text element | Circle element

这篇关于进度圆 - 在圆的末端画一个小圆弧 + 更多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆