web-dev-qa-db-ja.com

純粋なCSSでアニメーション化された弧を描く

Svgとcanvasで円弧を描画してアニメーション化できることは知っています。しかし、それはCSSで可能ですか?

次の方法で弧を作成しました。

.arc{
    width:150px;
    height:400px;
    border-radius:50%;
    border-right:1px solid black;
    border-left:1px solid black;
    border-top:1px solid black;
    border-bottom:1px solid white;
}

元のフィドル: http://jsfiddle.net/YGKWT/ (リンク切れ)

しかし、どうすればこれをアニメーション化できますか?私が考えることができる唯一の方法は、その上に真っ白なdivを置き、そのdivを右にスライドさせると弧が徐々に現れることです。もっと良い方法はありますか?

編集:

これが私が探しているアニメーションのタイプです: http://jsfiddle.net/nQLY7/ (リンク切れ)

12
Conqueror

この記事をチェックしてみてください。ChrisCoyierが円グラフアニメーションに関する記事を書いています。これは、水色の背景を削除した場合のデモと基本的に同じです。enter image description here

記事: http://css-tricks.com/css-pie-timer/

デモ: http://codepen.io/HugoGiraudel/pen/BHEwo

8
iConnor

これは、ハードコードされた変数を最小限に抑えたデモです。これは、アニメーション化された円の半分に基づいて機能します。

.circle {
  display: inline-flex;
  overflow: hidden;
}

.circle__half {
  height: 200px;
  width: 100px;
  position: relative;
  overflow: hidden;
}

.circle__half:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 100px 0 0 100px;
  background-color: Lime;
  transform-Origin: 100% 50%;
  /* hidden by default */
  transform: rotate(180deg);
  opacity: 0.65;
  animation-name: rotate-circle-half;
  animation-duration: 4s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

.circle__half--right {
  transform: scale(-1, -1);
}

.circle .circle__half--right:before {
  animation-name: rotate-circle-half--right;
}

/* show half of circle half of the time */
@keyframes rotate-circle-half {
  0% {
    transform: rotate(180deg);
  }
  50% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

@keyframes rotate-circle-half--right {
  0% {
    transform: rotate(180deg);
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(0deg);
  }
}
<div class="circle">
  <div class="circle__half"></div>
  <div class="circle__half circle__half--right"></div>
</div>

また、外観は iConnorの回答 と同じですが、ハードコードされたbackground-colorの欠点はありません。

*,
*:before,
*:after {
  box-sizing: border-box;
}

.circle {
  display: inline-flex;
  overflow: hidden;
}

.circle__half {
  height: 200px;
  width: 100px;
  position: relative;
  overflow: hidden;
}

.circle__half:before {
  height: inherit;
  width: inherit;
  position: absolute;
  content: "";
  border-radius: 100px 0 0 100px;
  border: 10px solid #00507c;
  border-right-color: transparent;
  background-color: #0087cf;
  transform-Origin: 100% 50%;
  /* hidden by default */
  transform: rotate(180deg);
  opacity: 0.65;
  animation-name: rotate-circle-half;
  animation-duration: 4s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

.circle__half--right {
  transform: scale(-1, -1);
}

.circle .circle__half--right:before {
  animation-name: rotate-circle-half--right;
}

/* show half of circle half of the time */
@keyframes rotate-circle-half {
  0% {
    transform: rotate(180deg);
  }
  50% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

@keyframes rotate-circle-half--right {
  0% {
    transform: rotate(180deg);
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(0deg);
  }
}
<div class="circle">
  <div class="circle__half"></div>
  <div class="circle__half circle__half--right"></div>
</div>
3

唯一のCSS3が必要な場合は、width + heightを設定し、border-radius100%に設定し、余分な境界線を無効にします(1または2のみを使用)。それにいくつかの良いピクセルを追加します。

次に、animate: time animation ease timingFunction;を使用してアニメーション化できます@-prefix-keyframes { . . . }を使用してアニメーション自体を宣言します(そうですね、ほとんどのブラウザエンジンには、この接頭辞が必要なようです、chromeは:S)I私があなたの意味に近いものがあると思います:

.qLoader2 {
  border: 4px solid blue;
  width: 10vw;
  height: 10vw;
  width: 72px;
  height: 72px;
  position: absolute;
  top: 12vh;
  right: 45vw;
  left: 45vw;
  background: white;
  opacity: 0.45;
  border-right: none;
  border-top: none;
  border-left: none;
  z-index: 2000;
  background-color: transparent;
  border-radius: 100%;
  transform: rotateZ(0);
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
}


/* @-moz-keyframes spin {  . . . } */


/* @-ms-keyframes spin {  . . . } */


/* @-o-keyframes spin { . . . } */

@-webkit-keyframes spin {
  from {
    transform: rotateZ(0deg) scale(1);
  }
  50% {
    transform: rotateZ(540deg) scale(0.9);
    border-color: #0099ff;
  }
  to {
    transform: rotateZ(1080deg) scale(1);
  }
}

@keyframes spin {
  from {
    transform: rotateZ(0deg) scale(1);
  }
  50% {
    transform: rotateZ(540deg) scale(0.9);
    border-color: #0099ff;
  }
  to {
    transform: rotateZ(1080deg) scale(1);
  }
}
<div class="qLoader2"></div>

JSFiddle

自由に使用および変更してください。あるいは、SVGを使用して何かを確認することもできます。これもかなりまともで、最近のほとんどのブラウザーでサポートされています。

2
Felype

編集:2つの弧を使用して、アニメーションを左から右にきれいに描画し、背景を透けて表示できます。

http://jsfiddle.net/sPv4A/6/

CSSに含まれないベンダープレフィックス:

.arcContain {
  width: 150px;
  height: 400px;
  position: relative;
  margin: 20px;
}

.arc {
  width: 150px;
  height: 400px;
  border-radius: 50%;
  border: 2px solid black;
  border-bottom: 2px solid transparent;
  position: absolute;
  top: 0;
  right: 0;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

.archideLeft .arc {
  top: auto;
  bottom: 0;
  right: auto;
  left: 0;
}

.archide {
  width: 50%;
  height: 0%;
  position: absolute;
  top: 0;
  right: 0;
  overflow: hidden;
  animation: appear 1.2s ease-in 1.2s forwards;
}

.archideLeft {
  top: auto;
  bottom: 0;
  right: auto;
  left: 0;
  animation: appear 1.2s ease-out forwards;
}

@keyframes appear {
  to {
    height: 100%;
  }
}
<div class="arcContain">
  <div class="archide archideLeft">
    <div class="arc"></div>
  </div>
  <div class="archide">
    <div class="arc"></div>
  </div>
</div>

古い答え:多分、2つの子divsを使用してそれを覆い、次に縮小してそれを明らかにします。

.arc {
  width: 150px;
  height: 400px;
  border-radius: 50%;
  border-right: 1px solid black;
  border-left: 1px solid black;
  border-top: 1px solid black;
  border-bottom: 1px solid white;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  position: relative;
}

.arcInner {
  background: white;
  height: 402px;
  width: 77px;
  position: absolute;
}

.arcLeft {
  top: -2px;
  left: -2px;
  -webkit-transition: height 2s linear;
  -moz-transition: height 2s linear;
  -ms-transition: height 2s linear;
  -o-transition: height 2s linear;
  transition: height 2s linear;
}

.arcRight {
  bottom: 0;
  right: -2px;
  -webkit-transition: height 2s 2s linear;
  -moz-transition: height 2s 2s linear;
  -ms-transition: height 2s 2s linear;
  -o-transition: height 2s 2s linear;
  transition: height 2s 2s linear;
}

.appear .arcInner {
  height: 0;
}
<div class="arc">
  <div class="arcInner arcLeft"></div>
  <div class="arcInner arcRight"></div>
</div>
1
Ben Jackson

元の質問に関するChris Bの提案に従って、答えは別のdivに弧を含め、次にコンテナーの幅をアニメーション化することです。

http://jsfiddle.net/AZb3X/

CSS:

body{
    background:orange;    
}

.arc{
    width:150px;
    height:400px;
    border-radius:50%;
    border-right:1px solid black;
    border-left:1px solid black;
    border-top:1px solid black;
    border-bottom:1px solid white;
    float:left;
}

.hider{
    width:0px;
    overflow:hidden;    
    -webkit-animation:unhide 12s;
}

@-webkit-keyframes unhide{
    100%{width:400px}
}    

HTML:

<div class='hider'>
    <div class="arc"></div>
</div>
0
Conqueror

私は少し遅れるかもしれませんが、私は2つの「隠線」を使用して、1つを上下に翻訳すると少し見栄えがよくなると思います。

実施例

<div class="wrap">
    <div class="arc"></div>
</div>

body {
    background:orange;
}
.wrap {
    position:absolute;
    height:400px;
    width:170px;
    overflow: hidden;
}
.arc {
    position:absolute;
    width:150px;
    height:400px;
    margin:10px;
    border-radius:50%;
    border-right:1px solid black;
    border-left:1px solid black;
    border-top:1px solid black;
    border-bottom:1px solid transparent;
}
.arc:before {
    content:"";
    position:absolute;
    left:-1px;
    top:-2px;
    background: orange;
    width:76px;
    height:375px;
    animation:unhide1 5s linear both;
}
.arc:after {
    content:"";
    position:absolute;
    left:75px;
    top:-2px;
    background: orange;
    float: right;
    width:76px;
    height:375px;
    animation: unhide2 5s linear 5s both;
}
@keyframes unhide1 {
    100% {
        transform: translatey(-375px);
    }
}
@keyframes unhide2 {
    100% {
        transform: translatey(375px);
    }
}
0
apaul