Jeron Gunn
Jeron Gunn

Reputation: 45

Creating a border animation on circle

I want to animate the middle circle's borders to start off with nothing and rotate to complete the circle (classes .cir3 & .cir4) almost like a spinner(page loader) without the repeating.

Fiddle

I changed them to black so they are easy to identify.

Here is a close example(bottom row) of what I'm looking for except I want it to complete the circle and not repeat like this

I just need someone to point me the right direction. JS Fiddle is Cleaner code.

$(function() {

  $('.cir5').click(function() {
    $(this).rotate({ count:3, duration:3.5, easing:'ease-out' });
  }).click();

  $('.cir').click(function() {
    $(this).rotate({ count:4, duration:1.6, easing:'ease-out' });
  }).click();
setTimeout(function() {
    $('.cir3').addClass('activecir');
}, 7500);
setTimeout(function() {
    $('.cir4').addClass('activecir');
}, 9000);
setTimeout(function() {
    $('.line2').addClass('info-text-active');
}, 6000);

setTimeout(function() {
    $('.line3').addClass('info-text-active');
}, 7500);
setTimeout(function() {
    $('.line4').addClass('info-text-active1');
}, 9000);
});

$.fn.rotate=function(options) {
  var $this=$(this), prefixes, opts, wait4css=0;
  prefixes=['-Webkit-', '-Moz-', '-O-', '-ms-', ''];
  opts=$.extend({
    startDeg: false,
    endDeg: 360,
    duration: 1,
    count: 1,
    easing: 'linear',
    animate: {},
    forceJS: false
  }, options);

  function supports(prop) {
    var can=false, style=document.createElement('div').style;
    $.each(prefixes, function(i, prefix) {
      if (style[prefix.replace(/\-/g, '')+prop]==='') {
        can=true;
      }
    });
    return can;
  }

  function prefixed(prop, value) {
    var css={};
    if (!supports.transform) {
      return css;
    }
    $.each(prefixes, function(i, prefix) {
      css[prefix.toLowerCase()+prop]=value || '';
    });
    return css;
  }

  function generateFilter(deg) {
    var rot, cos, sin, matrix;
    if (supports.transform) {
      return '';
    }
    rot=deg>=0 ? Math.PI*deg/180 : Math.PI*(360+deg)/180;
    cos=Math.cos(rot);
    sin=Math.sin(rot);
    matrix='M11='+cos+',M12='+(-sin)+',M21='+sin+',M22='+cos+',SizingMethod="auto expand"';
    return 'progid:DXImageTransform.Microsoft.Matrix('+matrix+')';
  }

  supports.transform=supports('Transform');
  supports.transition=supports('Transition');

  opts.endDeg*=opts.count;
  opts.duration*=opts.count;

  if (supports.transition && !opts.forceJS) { // CSS-Transition
    if ((/Firefox/).test(navigator.userAgent)) {
      wait4css=(!options||!options.animate)&&(opts.startDeg===false||opts.startDeg>=0)?0:25;
    }
    $this.queue(function(next) {
      if (opts.startDeg!==false) {
        $this.css(prefixed('transform', 'rotate('+opts.startDeg+'deg)'));
      }
      setTimeout(function() {
        $this
          .css(prefixed('transition', 'all '+opts.duration+'s '+opts.easing))
          .css(prefixed('transform', 'rotate('+opts.endDeg+'deg)'))
          .css(opts.animate);
      }, wait4css);

      setTimeout(function() {
        $this.css(prefixed('transition'));
        if (!opts.persist) {
          $this.css(prefixed('transform'));
        }
        next();
      }, (opts.duration*1000)-wait4css);
    });

  } else { // JavaScript-Animation + filter
    if (opts.startDeg===false) {
      opts.startDeg=$this.data('rotated') || 0;
    }
    opts.animate.perc=100;

    $this.animate(opts.animate, {
      duration: opts.duration*1000,
      easing: $.easing[opts.easing] ? opts.easing : '',
      step: function(perc, fx) {
        var deg;
        if (fx.prop==='perc') {
          deg=opts.startDeg+(opts.endDeg-opts.startDeg)*perc/100;
          $this
            .css(prefixed('transform', 'rotate('+deg+'deg)'))
            .css('filter', generateFilter(deg));
        }
      },
      complete: function() {
        if (opts.persist) {
          while (opts.endDeg>=360) {
            opts.endDeg-=360;
          }
        } else {
          opts.endDeg=0;
          $this.css(prefixed('transform'));
        }
        $this.css('perc', 0).data('rotated', opts.endDeg);
      }
    });
  }

  return $this;
};
.container {
	margin-top: 201px;
	margin-left: 200px;
}
.cir {
	background-color:transparent;
	width: 150px;
	height: 150px;
	border-radius: 150px;
	border:2px solid #4FAE7D;
}

.half-circle {
    width: 70px;
    height: 35px;
    /* background-color: gold; */
    border-top-left-radius: 50px;
    border-top-right-radius: 50px;
    border: 2px solid #4FAE7D;
    border-bottom: 0;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
    float: left;
	margin-left: 80px;
	margin-top: 15px;
	transform: rotate(-50deg);
	background: white;
}

.cir2 {
	background-color:white;
	width: 50px;
	height: 50px;
	border-radius: 40px;
	border:2px solid #4FAE7D;
	float: left;
	margin-left: 5px;
	margin-top: -60px;
}
.outside-cir2 {
	background-color:white;
	width: 60px;
	height: 60px;
	border-radius: 40px;
	border:2px solid white;
	margin-left: 1px;
	margin-top: 1px;
}
.inside-cir2 {
	background-color:white;
	width: 30px;
	height: 30px;
	border-radius: 30px;
	border:3px solid #4FAE7D;
	margin-left: 7px;
	margin-top: 7px;
}
.line1 {
   border:1px solid #4FAE7D;
   transform: rotate(40deg);
   margin-top: 72px;
   position: relative;
}

.line2 {
  border-top:2px solid #4FAE7D;
  width:0px;
  transform: rotate(20deg);
  transform-origin: 0% 0%;
  margin-left: 152px;
  margin-top:-23px;
-webkit-transition: width 2s; /* Safari */
    transition: width 2s;
}
.line3 {
  border-top:2px solid #4FAE7D;
  width:0px;
  transform: rotate(-40deg);
  transform-origin: 0% 0%;
  margin-left: 315px;
  margin-top:34px;
  -webkit-transition: width 2s; /* Safari */
    transition: width 2s;
}
.line4 {
  border-top:2px solid #4FAE7D;
  width:0px;
  transform: rotate(42deg);
  transform-origin: 0% 0%;
  margin-left: 453px;
  margin-top:-83px;
   -webkit-transition: width 2s; /* Safari */
    transition: width 2s;
}

.line5 {
  border-top:2px solid #2CB0D4;
  width:115px;
  transform: rotate(-35deg);
  transform-origin: 0% 0%;
  margin-left: 43px;
  margin-top:100px;
}

.fader { width: 120px; }
.cir3 {
	background-color:transparent;
	width: 50px;
	height: 50px;
	border-radius: 40px;
	border:2px solid black;
	float: left;
	margin-left: 264px;
	margin-top: 20px;
	opacity: 0;
	   -webkit-transition: width 15s; /* Safari */
    transition: width 15s;
}

.inside-cir3 {
	background-color:white;
	width: 10px;
	height: 10px;
	border-radius: 30px;
	border:15px solid #4FAE7D;
    margin-top: 5px;
    margin-left: 5px;
}

.cir4 {
	background-color:white;
	width: 50px;
	height: 50px;
	border-radius: 40px;
	border:2px solid black;
	float: left;
	margin-left: 401px;
	margin-top: -160px;
	opacity: 1;
	   -webkit-transition: width 15s; /* Safari */
    transition: width 15s;
}

.inside-cir4 {
	background-color:white;
	width: 30px;
	height: 30px;
	border-radius: 30px;
	border:3px solid #4FAE7D;
    margin-top: 7px;
    margin-left: 7px;
}

.cir5 {
	background-color:transparent;
	width: 150px;
	height: 150px;
	border-radius: 150px;
	border:2px solid #2CB0D4;
	margin-left: 573px;
}

.cir6 {
	background-color:transparent;
	width: 50px;
	height: 50px;
	border-radius: 40px;
	border:2px solid #2CB0D4;
	margin-left: -5px;
	margin-top: -15px;
}

.info-text-active { width: 120px; }
.info-text-active1 { width: 160px; }
.activecir { opacity: 1; }
<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="css/css.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<html>
<body>
<div class="container">
	<div class="cir">
	
	<div class="line1"></div>

	<div class="half-circle">
		<div class="outside-cir2"></div>
		  <div class="cir2">
			<div class="inside-cir2"></div>
		  </div>
	</div>
</div>
	<div class="line2 "></div>
	<div class="cir3">
		<div class="inside-cir3"></div>
	</div>
	<div class="line3"></div>
	<div class="cir4">
		<div class="inside-cir4"></div>
	</div>

	<div class="line4"></div>
	<div class="cir5"> 
		<div class="line5"></div>
		<div class="cir6"></div>
	</div>
</div>
</body>
</html>

Upvotes: 2

Views: 1208

Answers (1)

Pixelomo
Pixelomo

Reputation: 6737

This can very easily be done with SVG

This article will teach you how to do it

The essence of it is that you're animating the SVG stroke (the shapes line/border)

By offsetting this by the length of itself it initially appears not to be there, then using CSS animation you animate the offset back to the point where it's completed the circle

stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
See the Pen Basic Example of SVG Line Drawing, Backward and Forward by Chris Coyier (@chriscoyier) on CodePen.

Upvotes: 1

Related Questions