如何在悬停时使用css3或画布创建动画边框?

时间:2015-04-27 19:48:32

标签: html5 css3 canvas

我需要在hovering时创建一个动画边框。我尝试使用css3但无法获得完美的解决方案。

我的例外输出:

Image

所以我喜欢在悬停时创建一个像上面这样的animated border图像。基本上我需要在悬停时draw a border

请帮助任何人实现此解决方案。

提前致谢。

2 个答案:

答案 0 :(得分:4)

你可以用SVG做到这一点虽然我不认为这只有一种形状是可能的,但我可能是错的。您可以使用两个重叠<ellipse>来完成此操作。第三个例子与你的图形更相似......

&#13;
&#13;
svg {
  width: 125px;
  height: 125px;
  transform: rotate(-90deg);
}

.svg_2,
.svg_3{
  transform: rotate(-130deg);
}

/* 377 is roughly the circumference of the circle */
/*...if you change the size you will need to alter this value too*/
.circle {
  stroke-dasharray: 377; 
  stroke-dashoffset: 377;
  transition: all 1s ease;
}

.svg_3 .circle {
  stroke-dashoffset: 294;
}

.svg_1:hover .circle {
  stroke-dashoffset: 0;
}

.svg_2:hover .circle {
  stroke-dashoffset: 0;
}

.svg_3:hover .circle {
  stroke-dashoffset: 0;
}
&#13;
<svg class="svg_1" xmlns="http://www.w3.org/2000/svg">
 <g>
  <ellipse ry="60" rx="60" cy="62.5" cx="62.5" stroke-width="5" stroke="#000000" fill="#ffffff"/>
  <ellipse ry="60" rx="60" class="circle" cy="62.5" cx="62.5" stroke-width="5" stroke="#00c81c" fill="transparent"/>
 </g>
</svg>

<svg class="svg_2" xmlns="http://www.w3.org/2000/svg">
 <g>
  <ellipse ry="60" rx="60" cy="62.5" cx="62.5" stroke-width="5" stroke="#000000" fill="#ffffff"/>
  <ellipse ry="60" rx="60" class="circle" cy="62.5" cx="62.5" stroke-width="5" stroke="#00c81c" fill="transparent"/>
 </g>
</svg>

<svg class="svg_3" xmlns="http://www.w3.org/2000/svg">
 <g>
  <ellipse ry="60" rx="60" cy="62.5" cx="62.5" stroke-width="5" stroke="#000000" fill="#ffffff"/>
  <ellipse ry="60" rx="60" class="circle" cy="62.5" cx="62.5" stroke-width="5" stroke="#00c81c" fill="transparent"/>
 </g>
</svg>
&#13;
&#13;
&#13;

CodePen Version

答案 1 :(得分:1)

以下是如何在html画布中执行此操作:

  • 侦听mousemove事件并设置一个标志,指示鼠标是否在圈内。

  • 运行一个动画循环,在悬停时绘制一个增加的弧,在模糊时绘制一个减小的弧。

以下是示例代码和演示:

&#13;
&#13;
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }

var PI=Math.PI;
var PI2=PI*2;
var sweep=0;
var radius=50;
var linewidth=10;
var hoverState='new';
var isInside=false;

//    canvas.width=radius*2+linewidth;
//    canvas.height=radius*2+linewidth;
var cw=canvas.width;
var ch=canvas.height;
var cx=cw/2;
var cy=ch/2;
ctx.lineWidth=linewidth;

ctx.beginPath();
ctx.strokeStyle='black';
ctx.arc(cx,cy,radius,0,PI2);
ctx.stroke();

requestAnimationFrame(animate);

$("#canvas").mousemove(function(e){handleMouseMove(e);});


function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // Put your mousemove stuff here
  var dx=mouseX-cx;
  var dy=mouseY-cy;
  isInside=dx*dx+dy*dy<radius*radius;
}


function animate(time){

  hoverState=isInside?'hovering':'bluring';

  if(hoverState=='hovering'){sweep+=PI/20;}
  if(hoverState=='bluring'){sweep-=PI/20;}
  if(sweep>PI2){
    hoverState='idle';
    sweep=PI2;
  }
  if(sweep<0){
    hoverState='idle';
    sweep=0;
  }

  // only redraw when hovering or bluring
  if(hoverState=='hovering' || hoverState=='bluring'){
    ctx.clearRect(0,0,cw,ch);
    //
    ctx.beginPath();
    ctx.strokeStyle='black';
    ctx.arc(cx,cy,radius,0,PI2);
    ctx.stroke();
    //
    ctx.beginPath();
    ctx.strokeStyle='green';
    ctx.arc(cx,cy,radius,-PI/2,-PI/2+sweep);
    ctx.stroke();
  }

  requestAnimationFrame(animate);
}
&#13;
body{ background-color: ivory; }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hover over the circle</h4>
<canvas id="canvas" width=200 height=200></canvas>
&#13;
&#13;
&#13;