Borders are animating one after one. Need help to animate all borders at same time
Here is running example jsfiddle

CSS

* {
    padding: 0;
    margin: 0;
    outline: none !important;
}
body {
    background: #E0D4D4;
    overflow: hidden;
}
.borders {
    height: 100vh;
    width: 100vw;
    position: absolute;
    display: inline-block;
    z-index: 1;
}
.border-t {
    position: absolute;
    z-index: 1;
    height: 1px;
    top: 60px;
    left: 60px;
width: calc(100% - 60px * 2);
}
.border-t-l-wrap, .border-t-r-wrap {
    position: absolute;
    top: 0;
    height: 100%;
    overflow: hidden;
}
.border-t-l-wrap {
    left: 0;
    width: 50%;
}
.border-t-r-wrap {
    right: 60px;
    width: calc(50% - 60px);
}
.border-t-l {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    transform: translate3d(100%, 0, 0);
}
.border-t-r {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    transform: translate3d(-100%, 0, 0);
}
.border-r {
    position: absolute;
    z-index: 1;
    width: 1px;
    top: 60px;
    right: 60px;
height: calc(100% - 60px * 2);
}
.border-r-t-wrap {
    top: 60px;
    height: calc(50% - 60px);
}
.border-r-t, .border-r-b {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    overflow: hidden;
}
.border-r-t-wrap, .border-r-b-wrap {
    position: absolute;
    left: 0;
    width: 100%;
    overflow: hidden;
}
.border-r-b-wrap {
    bottom: 0;
    height: 50%;
}
.border-r-t {
    transform: translate3d(0, 100%, 0);
}
.border-r-b {
    transform: translate3d(0, -100%, 0);
}
.border-b {
    position: absolute;
    z-index: 1;
    height: 1px;
    bottom: 60px;
    left: 60px;
width: calc(100% - 60px * 2);
}
.border-b-l-wrap, .border-b-r-wrap {
    position: absolute;
    top: 0;
    height: 100%;
    overflow: hidden;
}
.border-b-l-wrap {
    left: 0;
    width: 50%;
}
.border-b-r-wrap {
    right: 0px;
    width: 50%
}
.border-b-l {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    transform: translate3d(100%, 0, 0);
}
.border-b-r {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    transform: translate3d(-100%, 0, 0);
}
.border-l {
    position: absolute;
    z-index: 1;
    width: 1px;
    top: 60px;
    left: 60px;
height: calc(100% - 60px * 2);
}
.border-l-t, .border-l-b {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #2a2a2a;
    opacity: 0.6;
    overflow: hidden;
}
.border-l-t-wrap, .border-l-b-wrap {
    position: absolute;
    left: 0;
    width: 100%;
    overflow: hidden;
    height: 50%;
}
.border-l-b-wrap {
    bottom: 0;
}
.border-l-t {
    transform: translate3d(0, 100%, 0);
}
.border-l-b {
    transform: translate3d(0, -100%, 0);
}
.animatebutton {
    position: relative;
    display: inline-block;
    margin: 0 auto;
    margin: 25% 35%;
    z-index: 900;
}
.animate1, .animate2 {
    height: 75px;
    width: 125px;
    display: inline-block;
    z-index: 1000
}
.animate1, .animate2 span {
    padding: 25px;
    display: inline-block;
}

HTML

<div class="borders">
  <div class="border-t">
    <div class="border-t-l-wrap">
      <div class="border-t-l"></div>
    </div>
    <div class="border-t-r-wrap">
      <div class="border-t-r"></div>
    </div>
  </div>
  <div class="border-r">
    <div class="border-r-t-wrap">
      <div class="border-r-t"></div>
    </div>
    <div class="border-r-b-wrap">
      <div class="border-r-b"></div>
    </div>
  </div>
  <div class="border-b">
    <div class="border-b-l-wrap">
      <div class="border-b-l"></div>
    </div>
    <div class="border-b-r-wrap">
      <div class="border-b-r"></div>
    </div>
  </div>
  <div class="border-l">
    <div class="border-l-t-wrap">
      <div class="border-l-t"></div>
    </div>
    <div class="border-l-b-wrap">
      <div class="border-l-b"></div>
    </div>
  </div>
</div>

<div class="animatebutton">
  <button class="animate1"><span>animate 1</span></button>
  <button class="animate2"><span>animate 2</span></button>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/easing/EasePack.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/plugins/CSSPlugin.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TimelineLite.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenLite.min.js"></script>

Script

jQuery(document).ready(function(event) {
"use strict";

var tl = new TimelineLite();

    $('.animate1').on('click', function(event) {

        tl.fromTo(".border-l-t", 1, {x:"0%", y:"100%"}, {x:"0%", y:"0%"});
        tl.fromTo(".border-l-b", 1, {x:"0%", y:"-100%"}, {x:"0%", y:"0%"});

        tl.fromTo(".border-r-t", 1, {x:"0%", y:"100%"}, {x:"0%", y:"0%"});
        tl.fromTo(".border-r-b", 1, {x:"0%", y:"-100%"}, {x:"0%", y:"0%"});

        tl.fromTo(".border-t-l", 1, {x:"100%", y:"0%"}, {x:"0%", y:"0%"});
        tl.fromTo(".border-t-r", 1, {x:"-100%", y:"0%"}, {x:"0%", y:"0%"});

        tl.fromTo(".border-b-l", 1, {x:"100%", y:"0%"}, {x:"0%", y:"0%"});
        tl.fromTo(".border-b-r", 1, {x:"-100%", y:"0%"}, {x:"0%", y:"0%"});     

    });

    $('.animate2').on('click', function(event) {

        tl.fromTo(".border-l-t", 0.5, {x:"0%", y:"0%"}, {x:"0%", y:"100%"}).to(".border-l-t", 1.3, {x:"0%", y:"0%"});
        tl.fromTo(".border-l-b", 0.5, {x:"0%", y:"0%"}, {x:"0%", y:"-100%"}).to(".border-l-b", 1.3, {x:"0%", y:"0%"});

        tl.fromTo(".border-r-t", 0.5, {x:"0%", y:"0%"}, {x:"0%", y:"100%"}).to(".border-r-t", 1.3, {x:"0%", y:"0%"});
        tl.fromTo(".border-r-b", 0.5, {x:"0%", y:"0%"}, {x:"0%", y:"-100%"}).to(".border-r-b", 1.3, {x:"0%", y:"0%"});

        tl.fromTo(".border-t-l", 0.5, {x:"0%", y:"0%"}, {x:"100%", y:"0%"}).to(".border-t-l", 1.3, {x:"0%", y:"0%"});
        tl.fromTo(".border-t-r", 0.5, {x:"0%", y:"0%"}, {x:"-100%", y:"0%"}).to(".border-t-r", 1.3, {x:"0%", y:"0%"});

        tl.fromTo(".border-b-l", 0.5, {x:"0%", y:"0%"}, {x:"100%", y:"0%"}).to(".border-b-l", 1.3, {x:"0%", y:"0%"});
        tl.fromTo(".border-b-r", 0.5, {x:"0%", y:"0%"}, {x:"-100%", y:"0%"}).to(".border-b-r", 1.3, {x:"0%", y:"0%"});

    });
})(jQuery);

Recommended Answers

All 9 Replies

Your code as it stands does its work on one border at a time. So you have to upend the whole design and think about the animation loop to be not one border at a time but work on all borders inside a single loop.

So how to do that? I'm thinking that the loop would be from say 0 (zero) to 100% and inside that loop would be your draw commands.

In Psuedo code.

for i = 0 to 100 percent
draw top border (just the percent of the border math goes here)
draw bottom border (just the percent of the border math goes here)
draw left border (just the percent of the border math goes here)
draw right border (just the percent of the border math goes here)
next i

If it seems sluggish you can add a step to the for loop to move in 2 percent steps rather than one.

The author of that jsfiddle (which is not you obviously) used GSAP and then in particular the TimeLineLite plugin, so if you want to make your own adjustments to the sequence of the border animation, you have to learn first how the TimeLineLite plugin works in regards to its sequence method.

https://greensock.com/docs/TimelineLite

@both
Thanks

@rproffitt
I was using jquery-transform plugin for the same animation, but I found GSAP more usefull. I tried TweenLite, TweenMax, TimelineLite, TimelineMax. TimelineLite() & TweenLite() is working for me.

TweenLite.fromTo animates all borders at same time, but it only works for first animation i.e. .animate1, TweenLite is not working for second animation i.e. .animate2.

TweenLite works okay for fromTo & stops working when another .to() is added like in second animation

@gentlemedia
I got problem because I'm writing my code. I'm the author of that jsfiddle.

Ah ok... apologies for assuming that!

@T. This is why, and mind you this is how I'd code it, flip the design to where the outer loop is what percentage of the line to draw with calls inside the loop for the actual draw. This is a classic design I used way back when on other than web pages. It's old, so old.

Although I do find it a lot of code for such a simple animation. Are you planning to use GSAP more in this project or is it only for this animation? None the less it's a lot of CSS and HTML (with loads of empty div tags to create faux borders).

I couldn't resist to play with animated borders as well :) but I've used ::before and ::after pseudo elements to create faux borders and CSS transitions for the animations. The only JS used is to trigger the border animation with the button. No libraries involved.

https://codepen.io/gentlemedia/pen/XPePbq

HTML:

<div class="box">
  <h1 class="title">border animation</h1>
</div>

<button>button</button>

CSS:

.box {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  width: 400px;
  height: 200px;
  margin: 100px auto 40px;
  border: 1px solid #eee;
}

.box::before,
.box::after,
.title::before,
.title::after {
  content: " ";
  position: absolute;
  background-color: #666;
  transition: .5s;
}

.box::before,
.box::after {
  width: 0;
  height: 1px;
}

.box.borders::before,
.box.borders::after {
  width: 100%;
}

.title::before,
.title::after {
  height: 0;
  width: 1px;
}

.box.borders .title::before,
.box.borders .title::after {
  height: 100%;
}

.box::before,
.title::before {
  top: 0;
  left: 0;
}

.box::after,
.title::after {
  bottom: 0;
  right: 0;
}

JS:

var box = document.querySelector('.box');
var button = document.querySelector('button');

button.onclick = function() {
  box.classList.toggle('borders');
}

I'm working on big project where I have many animations to handle, or otherwise there is jquery transform plugin to handle border animation. But I cant use different jquery plugins for each and every different animation. So I'm trying to manage animations with just GSAP.

I have not used GSAP before, So I'm still struggling with GSAP

I haven't used GSAP before too, because for complex anmiations I resort to http://animejs.com/

But... if I can do simple animations such as your border animation witrh CSS and a few lines of HTML & JS, then that's the first route I'd take. Especially with big projects, you want to keep things as lightweight as possible to have a speedy website.

If you have to create also compex animations with lot's of sequences, then do those with GSAP.

Anyway...

TweenLite.fromTo animates all borders at same time, but it only works for first animation i.e. .animate1

If I click on animate1 button in your jsfiddle, then all the borders don't animate at the same time. If the 1st border animation has finished it starts the 2nd border animation and after that the 3rd and so on.
As far as I can tell this is how it should be with TimelineLite()So I'm not sure why you say they all animate at the same time.

http://jsfiddle.net/cryzqu7b/

Check the difference between animate1 & animate 2.

I'll try animejs

But as I said, I have too many animations to handle keeping project lightweight

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.