CSS Animation Test

Dynamically changing the "from" part in an animation so that it uses the current location of the dot. Involves creating a keyframes string to inject into a style element and then applying the appropriate animation to the dot element.

by Travis Almand

HTML

<style id='keyframes'></style>

<p>Click on any box and dot shall move there. Dot will move from any box to any other box.</p>

<div id='box1'>1</div>
<div id='box2'>2</div>
<div id='box3'>3</div>
<div id='box4'>4</div>
<div id='path1'></div>
<div id='path2'></div>

<div id='dot'></div>

CSS

*, *:before, *:after {
    -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}

#dot {
    animation-duration: 1s;
    animation-fill-mode: forwards;
    animation-timing-function: linear;
    background: white;
    border: 2px solid black;
    border-radius: 50%;
    height: 20px;
    left: calc(50% - 10px);
    position: absolute;
    top: calc(50% - 10px);
    width: 20px;
}

#box1, #box2, #box3, #box4 {
    background: black;
    color: white;
    font-weight: bold;
    height: 100px;
    position: absolute;
    top: calc(50% - 50px);
    width: 100px;
}
#box1 {
    left: calc(25% - 50px);
}
#box2 {
    left: calc(75% - 50px);
}
#box3 {
    left: calc(50% - 50px);
    top: calc(75% - 50px);
}
#box4 {
    left: calc(50% - 50px);
    top: calc(25% - 50px);
}

#path1, #path2 {
    background: black;
    height: 5px;
    left: 25%;
    position: absolute;
    top: calc(50% - 2.5px);
    width: 50%;
}
#path2 {
    left: calc(50% - 2.5px);
    height: 50%;
    top: 25%;
    width: 5px;
}

JavaScript

var keyframes = document.getElementById('keyframes');
function setKeyframes(curX, curY) {
    var string = '@keyframes box1 { from { left: ' + curX + '; top: ' + curY + '; } 50% { left: calc(50% - 10px); top: calc(50% - 10px); } to { left: calc(25% - 10px); top: calc(50% - 10px); } }\r\n';
    string += '@keyframes box2 { from { left: ' + curX + '; top: ' + curY + '; } 50% { left: calc(50% - 10px); top: calc(50% - 10px); } to { left: calc(75% - 10px); top: calc(50% - 10px); } }\r\n';
    string += '@keyframes box3 { from { left: ' + curX + '; top: ' + curY + '; } 50% { left: calc(50% - 10px); top: calc(50% - 10px); } to { left: calc(50% - 10px); top: calc(75% - 10px); } }\r\n';
    string += '@keyframes box4 { from { left: ' + curX + '; top: ' + curY + '; } 50% { left: calc(50% - 10px); top: calc(50% - 10px); } to { left: calc(50% - 10px); top: calc(25% - 10px); } }\r\n';
    return string;
}


var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
var box3 = document.getElementById('box3');
var box4 = document.getElementById('box4');
var dot = document.getElementById('dot');

box1.addEventListener('click', function () {
    keyframes.textContent = setKeyframes(getComputedStyle(dot).left, getComputedStyle(dot).top);
    dot.style.animationName = 'box1';
});

box2.addEventListener('click', function () {
    keyframes.textContent = setKeyframes(getComputedStyle(dot).left, getComputedStyle(dot).top);
    dot.style.animationName = 'box2';
});

box3.addEventListener('click', function () {
    keyframes.textContent = setKeyframes(getComputedStyle(dot).left, getComputedStyle(dot).top);
    dot.style.animationName = 'box3';
});

box4.addEventListener('click', function () {
    keyframes.textContent = setKeyframes(getComputedStyle(dot).left, getComputedStyle(dot).top);
    dot.style.animationName = 'box4';
});