There are requirements in the project that could have been implemented using plug-ins and are readily available, but… I just wanted to implement one using CSS, so I looked up some related materials, articles, and…… I fell into a big hole

Results the following

As I made progress, I encountered more and more problems, which was beyond my expectation! However, have been so, more can not give up halfway, so, there is this article, record.

Expected browser compatibility: Chrome, FF needless to say, IE is only compatible with 9 and above.

Technology: VUE + CSS

The transform: Rotate () property of the CSS is used to create the rotate() function. The rotate() property of the CSS is used to create the rotate() function. The rotate() property of the CSS is used to create the rotate() function.

First define an external container, square of the same width and height, then add two child elements left and right, the height of the parent container, half the width of the parent container, the left of the rectangle set the top and left border-radius to 50%, so that it appears as a semicircle, the right of the rectangle is the same, except that the rounded corners are opposite the direction of the left. In this way, is just two rectangle joining together into one square, the next step to make it shown as a circle, need to add one more location in the parent container element, wide high setting depends on what you want circle shows that the width of the set of 50% rounded corners, so it locate in the parent container center position, both horizontal and vertical is implemented a circle. The following code

<div class="circle"> <div class="left" ref="circle_l"></div> <div class="right" ref="circle_r"></div> <div Class = "progress" > < span class = "score" > {{total}} < / span > points < / div > < / div >Copy the code
.circle {
  margin: 100px auto;
  position: relative;
  width: 128px;
  height: 128px;
}

.circle .progress {
  position: absolute;
  background-color: white;
  border-radius: 50%;
  text-align: center;
  width: 112px;
  height: 112px;
  top: 8px;
  left: 8px;
  line-height: 112px;
}
.circle .score {
  font-size: 46px;
  color: #007FFF;
}

.left,
.right {
  width: 64px;
  height: 128px;
  overflow: hidden;
  position: relative;
  float: left;
  background-color: #C4CFE3
}

.left {
  border-radius: 128px 0 0 128px;
}

.right {
  border-radius: 0 128px 128px 0;
}
Copy the code

The next step is to consider how to display the specific score. Add a pseudo-class to each of the left and right elements, and set the width and height of the pseudo-class to be the same as their own, and also set the rounded corners. Use the transform-Origin attribute to set the base position of the rotated element. In this way, the left and right elements are combined with their pseudo-classes to form a perfect circle, as shown in the figure

CSS code to add

.left:after,
.right:after {
    content: "";
    position: absolute;
    display: block;
    width: 64px;
    height: 128px;
    border-radius: 128px 0 0 128px;
    background-color: #007FFF;
}

.right:after {
    content: "";
    position: absolute;
    display: block;
    border-radius: 0 128px 128px 0;
}
.left:after {
    transform-origin: right center;
    transition: .4s;
    transform: rotateZ(40deg);
}

.right:after {
    transform-origin: left center;
    transform: rotateZ(180deg);
}
Copy the code

At this point, set the left::after transform property to rotateZ(40deg)

Next, combine the rotated DEG with the fraction. Since we divide the whole circle into two parts, the degree of rotation should also be considered separately. When <=50, we only consider changing the left::after. When >50, the left defaults to 0deg, and the rest only change the right::after

Because the whole circle is divided into 100 parts

1 = 3.6 deg.

On the left side of the

Rotation Angle = 180 – (known fraction ×3.6)

For example, if the score is 40, the rotation Angle = 180 – (40×3.6) = 36deg

On the right side

Rotation Angle = 180 – (known fraction -50)×3.6)

For example, if the score is 70, then the rotation Angle =180-((70-50)×3.6) = 108deg

Light such reasoning, practice can indeed achieve the desired effect, but!! The first pit came, I use vue to operate ah, that is because the use of pseudo class to control the rotation Angle, can, get pseudo class way has not used, a check, indeed there is!!

Increased knowledge!! GetComputedStyle (document.querySelector(‘.left’), ‘:after’).getPropertyValue(‘transform’). Next are methods that can change pseudo-class attributes

document.styleSheets[0].addRule('.left::after',`transform: rotateZ(90deg); `)Copy the code

Pro test is available!! However, when used in vUE, an error is reported

I this “give up” spirit, consider, feel that this is not suitable for doing this demand, if it is a fixed value, will not change, calculate a good Angle at the beginning, write dead in CSS may also be ok, but this seems to be not applicable. Although passed, but also learned a method to get and change the pseudo-class attributes of the element.

Then move on to the next one, but… This article is a little too long… The next option is to do so again in the next article: party O (╥﹏╥)o