COOL MENU EUY
ACTION BLOG


Light house
Setelah beberapa hari of karena lumayan sibuk dengan beragam kegiatan ditambah jaringan yang diganggu orang iseng , malam ini ada sedikit luang waktu dan saya akan mencoba untuk share sebuah menu yang cukup keren untuk ditempatkan pada sebuah template.Kesan pertama mungkin akan biasa tapi setelah brada meletakan kursor pada tombolnya , disitulah sensasi dimulai " wkwkwkwk".Untuk detail nya lihat demonya dibawah ini
See Demo
Komposisi : CSS /HTML/JAVASCRIPT

CSS


nav {
  left: 0;
  margin: -33px 0 0 0;
  position: absolute;
  text-align: center;
  top: 50%;
  width: 100%;
}
nav a {
  background: #2c2c2c;
  border: 4px solid transparent;
  box-shadow: 0 0 0 1px #3c3c3c, 0 0 0 2px #000;
  display: inline-block;
  font-size: 18px;
  font-weight: bold;
  height: 50px;
  line-height: 50px;
  margin: 0 3px;
  padding: 0 40px;
  position: relative;
  text-decoration: none;
  text-shadow: 0 -1px 1px #111;
  transition: all 400ms;
}

nav a.red { color: #f33; }
nav a.green { color: #3f3; }
nav a.blue { color: #39f; }
nav a.yellow { color: #ff3; }

nav a canvas {
  display: block;
  opacity: 0;
  position: absolute;
}

nav a:hover {
  background: #333;
  color: #fff;
}

HTML


<nav>
  <a href="#" class="red" data-speed="4" data-color="#f33">Red</a>
  <a href="#" class="green" data-speed="4" data-color="#3f3">Green</a>
  <a href="#" class="blue" data-speed="4" data-color="#39f">Blue</a>
  <a href="#" class="yellow" data-speed="4" data-color="#ff3">Yellow</a>
</nav>

JAVASCRIPT


(function(){for(var d=0,a=["webkit","moz"],b=0;b<a.length&&!window.requestAnimationFrame;++b)window.requestAnimationFrame=window[a[b]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[a[b]+"CancelAnimationFrame"]||window[a[b]+"CancelRequestAnimationFrame"];window.requestAnimationFrame||(window.requestAnimationFrame=function(b){var a=(new Date).getTime(),c=Math.max(0,16-(a-d)),e=window.setTimeout(function(){b(a+c)},c);d=a+c;return e});window.cancelAnimationFrame||(window.cancelAnimationFrame=
function(a){clearTimeout(a)})})();

var $elems = $('nav a');

function Border( opt ){
  this.elem = opt.elem;
  this.active = false;
  this.canvas = document.createElement('canvas');
  this.ctx = this.canvas.getContext('2d');
  this.width = this.canvas.width = this.elem.outerWidth();
  this.height = this.canvas.height = this.elem.outerHeight();
  this.borderSize = parseInt(this.elem.css('border-left-width'), 10);
  this.waypoints = [
    [0, 0],
    [this.width - this.borderSize, 0],
    [this.width - this.borderSize, this.height - this.borderSize],
    [0, this.height - this.borderSize]
  ];
  this.tracer = {
    x: 0,
    y: 0,
    color: opt.color,
    speed: opt.speed,
    waypoint: 0
  };
  this.canvas.style.top = -this.borderSize + 'px';
  this.canvas.style.left = -this.borderSize + 'px';
  this.elem.append($(this.canvas));
}

Border.prototype.loop = function(){
  if(this.active){
    requestAnimationFrame($.proxy(this.loop, this));   
    this.ctx.globalCompositeOperation = 'destination-out';
    this.ctx.fillStyle = 'rgba(0, 0, 0, .05)';
    this.ctx.fillRect(0, 0, this.width, this.height);
    this.ctx.globalCompositeOperation = 'source-over';
    this.ctx.fillStyle = this.tracer.color;
    this.ctx.fillRect(this.tracer.x, this.tracer.y, this.borderSize, this.borderSize);
  
    var previousWaypoint = (this.tracer.waypoint == 0) ? this.waypoints[this.waypoints.length - 1] : this.waypoints[this.tracer.waypoint - 1],
        dxTotal = previousWaypoint[0] - this.waypoints[this.tracer.waypoint][0],
        dyTotal = previousWaypoint[1] - this.waypoints[this.tracer.waypoint][1],
        distanceTotal = Math.sqrt(dxTotal * dxTotal + dyTotal * dyTotal),  
        angle = Math.atan2(this.waypoints[this.tracer.waypoint][1] - this.tracer.y, this.waypoints[this.tracer.waypoint][0] - this.tracer.x),
        vx = Math.cos(angle) * this.tracer.speed,
        vy = Math.sin(angle) * this.tracer.speed, 
        dxFuture = previousWaypoint[0] - (this.tracer.x + vx),
        dyFuture = previousWaypoint[1] - (this.tracer.y + vy),
        distanceFuture = Math.sqrt(dxFuture * dxFuture + dyFuture * dyFuture);
    
    if(distanceFuture >= distanceTotal){
      this.tracer.x = this.waypoints[this.tracer.waypoint][0];
      this.tracer.y = this.waypoints[this.tracer.waypoint][1];
      this.tracer.waypoint = (this.tracer.waypoint == this.waypoints.length - 1) ? 0 : this.tracer.waypoint + 1;
    } else {
      this.tracer.x += vx;
      this.tracer.y += vy;
    }
  } else {
    this.ctx.clearRect(0, 0, this.width, this.height); 
  }
}

$elems.each(function(){
  var $this = $(this);
  var border = $this.data('border', new Border({
    elem: $this,
    color: $this.data('color'),
    speed: $this.data('speed')
  }));
  $this.data('border').loop();  
});

$elems.on('mouseenter', function(){
  var border = $(this).data('border');
  $(border.canvas).stop(true).animate({'opacity': 1}, 400);
  if(!border.active){
    border.active = true;
    border.loop();
  }
});

$elems.on('mouseleave', function(){
  var border = $(this).data('border');
  $(border.canvas).stop(true).animate({'opacity': 0}, 400, function(){
    border.active = false;
    border.tracer.x = 0;
    border.tracer.y = 0;
    border.tracer.waypoint = 0; 
  });   
});