I am experimenting with a tile-like layout for my site with which the user can interact. Each box is a button used to select a product, and upon selection of a product, the other boxes fade out and are hidden. This effect is toggle-able.
I have slightly modified the following fiddle that I found online, and it comes very close the desired result.
$('.box').click(function() {
$('.box').not(this).fadeToggle(250);
});
div.box {
width: 100px;
height: 63px;
background-color: #52c6ec;
margin: 5px;
padding-top: 37px;
float: left;
text-align: center;
color: #fff;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="box" id="box1">Box 1</div>
<div class="box" id="box2">Box 2</div>
<div class="box" id="box3">Box 3</div>
<div class="box" id="box4">Box 4</div>
<div class="box" id="box5">Box 5</div>
<div class="box" id="box6">Box 6</div>
<div class="box" id="box7">Box 7</div>
<div class="box" id="box8">Box 8</div>
<div class="box" id="box9">Box 9</div>
<div class="box" id="box10">Box 10</div>
<div class="box" id="box11">Box 11</div>
<div class="box" id="box12">Box 12</div>
<div class="box" id="box13">Box 13</div>
<div class="box" id="box14">Box 14</div>
<div class="box" id="box15">Box 15</div>
<div class="box" id="box16">Box 16</div>
<div class="box" id="box17">Box 17</div>
<div class="box" id="box18">Box 18</div>
<div class="box" id="box19">Box 19</div>
<div class="box" id="box20">Box 20</div>
The only thing I want to do is to have the selected item transition (via animation) to the top-left, rather than just appearing there. Preferably also during the fading of the other boxes.
Because I'm using floats here, I cannot figure out how to animate these, since they don't have any numeric properties.
Ideas for a jQuery solution? Thanks.
Is this what you want?
var t, l, loctop, locleft;
$('.box').click(function() {
var e = $(this);
if( $('.box').not(this).is(':visible') )
{
t = e.position().top + 'px';
l = e.position().left + 'px';
loctop = locleft = 0;
$(this).css( {position: 'fixed', top:t, left:l} );
$('.box').not(this).fadeToggle(550, function(){
$(e).animate({
top: loctop,
left: locleft
}, 800, function(){
$(this).stop(true, true);
});
});
}
else
{
loctop = parseInt(t);
locleft = parseInt(l);
$(e).animate({
top: loctop,
left: locleft
}, 800, function(){
$('.box').not(this).fadeIn(550, function(){
$(e).css( {position: 'relative', top:'', left:''} );
});
});
}
});
div.box {
width: 100px;
height: 63px;
background-color: #52c6ec;
margin: 5px;
padding-top: 37px;
float: left;
text-align: center;
color: #fff;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="box" id="box1">Box 1</div>
<div class="box" id="box2">Box 2</div>
<div class="box" id="box3">Box 3</div>
<div class="box" id="box4">Box 4</div>
<div class="box" id="box5">Box 5</div>
<div class="box" id="box6">Box 6</div>
<div class="box" id="box7">Box 7</div>
<div class="box" id="box8">Box 8</div>
<div class="box" id="box9">Box 9</div>
<div class="box" id="box10">Box 10</div>
<div class="box" id="box11">Box 11</div>
<div class="box" id="box12">Box 12</div>
<div class="box" id="box13">Box 13</div>
<div class="box" id="box14">Box 14</div>
<div class="box" id="box15">Box 15</div>
<div class="box" id="box16">Box 16</div>
<div class="box" id="box17">Box 17</div>
<div class="box" id="box18">Box 18</div>
<div class="box" id="box19">Box 19</div>
<div class="box" id="box20">Box 20</div>
Here's my attempt in vanilla JS (tested on Chrome and Firefox)
Basically it works only with CSS transitions over the transform
property for the selected element and over the opacity
for all the other elements. The fadeOut/In runs while the selected element is moving as you specified.
CodePen Demo
CSS
main {
display: flex;
flex-wrap: wrap;
border: 1px solid #ccc;
}
div {
background: #a0c6df;
width: 100px;
height: 100px;
border: 2px #8fa0c6 dashed;
margin: 10px;
opacity: 1;
cursor: pointer;
transition: all 1s;
}
main.fadeout div:not(.current) {
opacity: 0;
cursor: default;
}
JS
var main = document.querySelector('main');
var boxes = document.querySelectorAll('main div');
var animationIsRunning = false;
var getBoxPosition = function() {
[].forEach.call(boxes, function(b) {
var gBCR = b.getBoundingClientRect();
b.dataset.top = gBCR.top;
b.dataset.left = gBCR.left;
});
}
window.addEventListener('resize', function() {
var dc;
getBoxPosition();
if (dc = main.querySelector('div.current')) {
main.classList.remove('fadeout');
dc.classList.remove('current');
dc.style.transform = 'translate(0,0)';
}
});
main.addEventListener('click', function(evt) {
var b = evt.target,
left = 0,
top = 0;
/* listen to the div click event only */
if (b.nodeName.toLowerCase() !== 'div') { return false; }
/* don't listen if there's a current element and user clicked
over a hidden div */
if (
main.querySelector('.current') &&
!b.classList.contains('current')
) { return false; }
/* only if another animation is not running... */
if (!animationIsRunning) {
animationIsRunning = true;
b.classList.toggle('current');
main.classList.toggle('fadeout');
if (b.classList.contains('current')) {
left = b.dataset.left;
top = b.dataset.top;
}
b.style.transform = 'translate(-'+ left +'px, -'+ top +'px)';
}
});
main.addEventListener('transitionend', function() {
animationIsRunning = false;
});
getBoxPosition();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With