radial tree_攻壳机动队Radial Progress UI

radial tree

I’ve long enjoyed the user interface designs shown in anime like Ghost In The Shell, and realized this weekend I could recreate the visual design in . You can see the finished example above, and the complete code in the associated CodePen demo; this article breaks down my approach to the UI piece by piece.

我一直很喜欢动漫“ Ghost In The Shell”中展示的用户界面设计,并意识到这个周末我可以用重新创建视觉设计。 您可以在上面看到完整的示例,以及相关的CodePen演示中的完整代码; 本文逐条细分了我使用UI的方法。

标记 (The Markup)

The basic markup is a series of <circle> elements with increasing radii, all centered on the same point. There’s also a <text> element:

基本标记是一系列<circle>元素 ,它们的半径不断增加,所有元素都集中在同一点上。 还有一个<text>元素

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <circle cx="50" cy="50" r="22"></circle>
  <circle cx="50" cy="50" r="24"></circle>
  <circle cx="50" cy="50" r="26"> </circle>
  <circle cx="50" cy="50" r="30"></circle>
  <circle cx="50" cy="50" r="34"></circle>
  <circle cx="50" cy="50" r="34"></circle>
  <text x="49" y="54">0</text>
</svg>

Since the transformation and animation of elements in CSS and SVG is not yet the same, the circles are animated with SMIL. The markup is enhanced by placing <animate> elements inside each <circle>:

由于CSS和SVG中的元素的转换和动画尚不相同,因此使用SMIL对圆圈进行动画处理。 通过在每个<circle>内放置<animate>元素来增强标记:

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="gits">
  <circle cx="50" cy="50" r="22">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="360 50 50" dur="10s" repeatCount="indefinite" />
  </circle>
  <circle cx="50" cy="50" r="24">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="360 50 50" dur="8s" repeatCount="indefinite" />
  </circle>
  <circle cx="50" cy="50" r="26">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="-360 50 50" dur="8s" repeatCount="indefinite" />
  </circle>
  <circle cx="50" cy="50" r="30">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="360 50 50" dur="14s" repeatCount="indefinite" />
  </circle>
  <circle cx="50" cy="50" r="34">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="360 50 50" dur="18s" repeatCount="indefinite" />
  </circle>
  <circle cx="50" cy="50" r="34">
    <animateTransform attributeName="transform"
      attributeType="XML" type="rotate" from="0 50 50"
          to="-360 50 50" dur="20s" repeatCount="indefinite" />
  </circle>
  <text x="49" y="54">0</text>
</svg>

Some of the circles are rotating clockwise, some counter-clockwise, with different rotation speeds and indefinite (i.e. infinite) repetition. Note that the circles are 4 units apart.

一些圆圈顺时针旋转,一些圆圈逆时针旋转,具有不同的旋转速度和不确定的(即无限的)重复。 请注意,圆圈相隔4个单位。

CSS (CSS)

Since the the circles are solid, and animated on their centres, no animation is yet visible, even when we add CSS:

由于圆圈是实心的,并且在其中心具有动画效果,因此即使添加CSS,也看不到动画:

circle { 
  stroke: #000;
  fill: none;
  stroke-width: 4px;
  transition: .2s;
  stroke-dashArray: 0 600;
}
text {
  font-family: Titillium Web, sans-serif;
  font-size: 12px;
  text-anchor: middle;
}

The stroke-width is just enough to make the strokes of each circle meet, but not overlap; while stroke-dashArray is set height enough on the circles to not see any stroke at all, at least initially. The text-anchor places the text in the center; the transition will ease the animation to come.

stroke-width刚好足以使每个圆的笔触相遇,但不能重叠; 而stroke-dashArray在圆上设置的高度足以至少在初始时根本看不到任何笔触。 text-anchor将文本放置在中间; transition将简化动画的制作。

JavaScript (JavaScript)

So now the circles are spinning. They’re turned into circular segments with :

所以现在圈子在旋转。 它们通过变成了循环

var circles = document.getElementsByTagName("circle"),
progress = document.getElementsByTagName("text")[0];

We also need some random values, which can be derived from a function:

我们还需要一些随机值 ,这些可以从函数得出:

function getRandomInRange(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

The script uses a loop to determine the circumference of each circle. A random number between 20 and 80 is used to define the initial stroke-dasharray of each circle, with the circumference of the circle stored as a property:

该脚本使用循环来确定每个圆的周长。 使用20到80之间的随机数来定义每个圆的初始stroke-dasharray ,圆的周长作为属性存储:

for (var j = 0; j < circles.length; ++j) {
	var radius = parseInt(circles[j].getAttribute('r'), 10);
	circles[j].circumference = 2 * radius * Math.PI;
	circles[j].init = getRandomInRange(20,80);
	circles[j].style.strokeDasharray = circles[j].init + " " + circles[j].circumference;
}

The code originally used a for…of loop, but I discovered that Safari had a problem going over a SVG Nodelist in that way. I will explore that further in the future.

该代码最初使用for…of循环,但是我发现Safari在以这种方式遍历SVG Nodelist时遇到问题。 以后我会进一步探讨。

This forms each circle segment, allowing the animation to be seen.

这形成了每个圆弧段,从而可以看到动画。

var i = 0;
var timer = setInterval(function() { 
	progress.textContent = i;
		if (i == 100) {
			clearInterval(timer);
		} else {
  			i++;  
  			for (var j = 0; j < circles.length; ++j) {
       			circles[j].style.strokeDasharray = circles[j].init + i + " " + circles[j].circumference;
 			}
}}, 500)

The <text> element is filled with the value of i inside a timer every 500 milliseconds (i.e. every half second). The same value is used to increase the first value in the dashArray of each circle, slowly completing them.

<text>元素每500毫秒(即每半秒)在计时器内部填充i的值。 相同的值用于增加每个圆的dashArray中的第一个值,并逐渐完成它们。

改进措施 (Improvements)

There are several ways this could be improved:

有几种方法可以改进:

  • Not all of the circle segments complete when the timer finishes; the first stroke-dashArray value is large enough to complete the small inner circles, but not enough to finish the larger. I prefer the way it turned out, but you could alter the script to make the final state of the counter circles solid.

    计时器结束时,并非所有的圆弧段都完成; 第一个stroke-dashArray值足够大以完成较小的内圆,但不足以完成较大的内圆。 我更喜欢原来的方式,但是您可以更改脚本以使计数器圆圈的最终状态稳定。

  • ideally, the entire SVG would be generated by JavaScript, and the result used to replace an HTML5 <progress> element, building the UI progressively.

    理想情况下,整个SVG将由JavaScript生成,结果用于替换HTML5 <progress>元素 ,从而逐步构建UI。

  • You could also alter the completion of the segments so that they expanded at different rates, completing to a solid outline for each circle at the moment the timer finished.

    您还可以更改分段的完成程度,以使它们以不同的速度扩展,在计时器结束时为每个圆圈完成一个完整的轮廓。

翻译自: https://thenewcode.com/1139/Ghost-In-The-Shell-Radial-Progress-UI

radial tree

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值