CSS动画边框

时间:2015-04-02 16:12:19

标签: javascript css html5 css3 transition

我需要在div上制作动画边框。我想出了如何使用画布覆盖和一些javascript来做到这一点,但它现在是超级笨重的。无论如何用CSS动画完成同样的动画?请参阅此jsfiddle http://jsfiddle.net/L8ov2fk0/7/

编辑:很多很棒的答案!有些我发现了这个而其他人没有。我一直遇到的问题是,我的小提琴中的确切动画是客户想要的,我从来没有能够调整我发现的任何东西,甚至接近那个。

我的代码

HTML

<div id="buttona" class="button" >Button A</div>
<div id="buttonb" class="button" >Button B</div>

<canvas id="bordera"></canvas>
<canvas id="borderb"></canvas>

CSS

.button{
    padding:10px;
    border:1px solid red;
}
#buttona{
    position:absolute;
}

#buttonb{
    position: absolute;
    left:100px;
}

#bordera{
    position:absolute;
    width:81px;
    height:40px;
    pointer-events:none;
}

#borderb{
    position: absolute;
    left:100px;
    width:80px;
    height:40px;
    pointer-events:none;
}

的Javascript

$('body').on('click', '#buttona', function (){
    DrawButtonBorder("bordera");
});

$('body').on('click', '#buttonb', function (){
    DrawButtonBorder("borderb");
});



/*animated borders*/
function Point(x, y, width, height, half) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.half = half;
}

Point.prototype.increment = function () {
    if (this.half == "upper") {
        if (this.y > 0 && this.x == 0)
            this.y--;
        else if (this.y == 0 && this.x < this.width)
            this.x++;
        else if (this.y < this.height / 2 && this.x == this.width)
            this.y++;
    }
    else {
        if (this.y < this.height && this.x == 0)
            this.y++;
        else if (this.y == this.height && this.x < this.width)
            this.x++;
        else if (this.y > this.height / 2 && this.x == this.width)
            this.y--;
    }
}

animatedBorder = null;
borderDrawn = "";
function DrawButtonBorder(id) {
    if (borderDrawn != id) {
        borderDrawn = id;
        CancelButtonBorder();
        ClearButtonBorder("bordera");
        ClearButtonBorder("borderb");

        var speed = 1;
        var canvas = document.getElementById(id);
        var context = canvas.getContext('2d');

        var style = getComputedStyle(canvas);

        var width = parseInt(style.width.replace("px", ""));
        width = parseInt(width / speed);

        var height = parseInt(style.height.replace("px", ""));
        height = parseInt(height / speed);

        context.canvas.width = width;
        context.canvas.height = height;

        var middle = parseInt(height / 2);
        var a = new Point(0, middle, width, height, "upper");
        var b = new Point(0, middle, width, height, "lower");

        function draw() {

            //upper half
            context.strokeStyle = '#D7A95A';
            context.moveTo(a.x, a.y);
            a.increment();
            context.lineTo(a.x, a.y);
            context.stroke();

            //lower half
            context.strokeStyle = '#D7A95A';
            context.moveTo(b.x, b.y);
            b.increment();
            context.lineTo(b.x, b.y);
            context.stroke();


            if (a.y > middle && b.y < middle)
                return;
            animatedBorder = requestAnimFrame(draw);
        }
        draw();
    }
}

function ClearButtonBorder(id) {
    var canvas = document.getElementById(id);
    var context = canvas.getContext('2d');
    context.clearRect(0,0,context.canvas.width, context.canvas.height);
}

function CancelButtonBorder() {
    cancelAnimFrame(animatedBorder);
}

var requestAnimFrame = window.requestAnimationFrame ||
                        window.webkitRequestAnimationFrame ||
                        window.mozRequestAnimationFrame ||
                        function (callback) {
                            window.setTimeout(callback, 1000 / 60);
                        };

var cancelAnimFrame = window.cancelAnimationFrame ||
                        window.webkitCancelAnimationFrame ||
                        window.mozCancelAnimationFrame;

4 个答案:

答案 0 :(得分:2)

你可以使用背景图片或渐变和背景大小。

.button {
  padding:0.25em;
  display:inline-block;
  border:none;
  background-color:;
  background:
    linear-gradient(to top,red,red)  0 100%,
    linear-gradient(to right,red,red)100% bottom,
    linear-gradient(to top,red,red) bottom right ,
    linear-gradient(to top,red,red) top right  lightgray;
  background-size: 3px 0%, 0% 3px,3px 0%, 0% 3px;
  background-repeat:no-repeat,no-repeat,no-repeat,no-repeat;
  transition:1s;
  }
.button:hover {
  background-size: 3px 100%, 100% 3px,3px 100%, 100% 3px;
    
<button id="buttona" class="button" >Button A</button>
<button id="buttonb" class="button" >Button B</button>

或由背景阴影制作的动画

.button {
  padding:0.25em;
  display:inline-block;
  border:none;
  background-color:;
  background:
    linear-gradient(to top,red,red)  0 100%,
    linear-gradient(to right,red,red)100% bottom,
    linear-gradient(to top,red,red) bottom right ,
    linear-gradient(to top,red,red) top right  lightgray;
   background-size: 3px 100%, 100% 3px,3px 100%, 100% 3px;
  background-repeat:no-repeat,no-repeat,no-repeat,no-repeat;
  box-shadow:inset 0 0 0 0 lightgray;
  transition:1s;
  }
.button:hover {
  box-shadow:inset 5em 2em 0 0 lightgray
<button id="buttona" class="button" >Button A</button>
<button id="buttonb" class="button" >Button B</button>

其他CSS示例:http://codepen.io/gc-nomade/pen/IGliC http://codepen.io/gc-nomade/pen/bhxALhttp://codepen.io/gc-nomade/pen/pKwby

答案 1 :(得分:1)

创建一个div元素作为边框,将其放置在您希望动画边框发生的元素上。

.border{
    height: 10px; //Or whatever height for thickness
    background-color: black; //Or whichever color
    visibility: hidden; //So that it takes up space
}

单击该按钮时,将此类添加到border元素并将其可见性转为可见

.extend{
  animation: expand 3s;
  -webkit-animation: expand 3s;
}

在css中包含此操作

/* Chrome, Safari, Opera */
@-webkit-keyframes expand {
    from {width: 0%;}
    to {width: 100%;}
}

/* Chrome, Safari, Opera */
@keyframes expand {
    from {width: 0%;}
    to {width: 100%;}
}

答案 2 :(得分:1)

你可以使用border-image css style:

Here is the Example Fiddle

Another Example

#myDIV {
    border:15px solid transparent;
    width:250px;
    padding:10px 20px;
    border-image:url(http://www.w3schools.com/cssref/border.png) 30 30 stretch;
    transition: .2s;
}
#myDIV:hover{
    border-image:url(http://www.w3schools.com/cssref/border.png) 0 0 stretch;
}

答案 3 :(得分:1)

如果您将div转换为实际的<button>元素,则可以使用:focus伪类

来实现此效果

示例:http://codepen.io/anon/pen/QwPxYm

<button id="buttona" class="button">Button A</button>
<button id="buttonb" class="button">Button B</button>

CSS

.button {
    padding:10px;
    background: none;
    outline: none;
    border:1px solid red;
}

#buttona, #buttonb {
    position:absolute;
}

#buttonb {
    left:100px;
}

.button:after {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 0;
  display: block;
  width: 0;
  height: 0;
  border-top: 1px #ccc solid;
  transition: width 3s;
}

.button:focus:after {
  width: 100%;
}