Reputation: 59511
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.
Upvotes: 5
Views: 1742
Reputation: 838
Hope this will be very useful for you. I have created full working code You can use this.
var a=0;
$('.box').click(function() {
if(a==0){
var position = $(this).position();
$( "this" ).text( "left: " + position.left + ", top: " + position.top );
$(this).css({
"position":"absolute",
"left":position.left,
"top":position.top
})
$('.box').not(this).fadeOut(250);
$(this).animate({
"left":"0px",
"top":"0px"
}, 1000);
a=1;
}
else{
$('.box').not(this).fadeIn(250);
$(this).css({"position":"static"});
a=0;
}
});
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>
Upvotes: 0
Reputation: 123397
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.
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();
Upvotes: 2
Reputation: 1792
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>
Upvotes: 4
Reputation: 6538
Take a look at this awesome plugin (http://isotope.metafizzy.co/) from David Desandro
You can find an exemple on codepen here :
http://codepen.io/desandro/pen/nFrte
An exemple from isotope blog :
// external js: isotope.pkgd.js
var $notifElem;
$( document ).ready( function() {
var $grid = $('.grid').isotope({
itemSelector: '.grid-item',
masonry: {
columnWidth: 100
}
});
$grid.on( 'layoutComplete', function( event, laidOutItems ) {
console.log( 'layoutComplete with ' + laidOutItems.length + ' items' );
});
$grid.on( 'click', '.grid-item', function() {
// change size of item by toggling gigante class
$( this ).toggleClass('grid-item--gigante');
$grid.isotope('layout');
});
});
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
body {
font-family: sans-serif;
}
/* ---- grid ---- */
.grid {
background: #DDD;
max-width: 1200px;
}
/* clear fix */
.grid:after {
content: '';
display: block;
clear: both;
}
/* ---- .grid-item ---- */
.grid-item {
float: left;
width: 100px;
height: 100px;
background: #0D8;
border: 2px solid #333;
border-color: hsla(0, 0%, 0%, 0.7);
}
.grid-item--width2 { width: 200px; }
.grid-item--height2 { height: 200px; }
.grid-item:hover {
background: #8CF;
cursor: pointer;
}
.grid-item--gigante {
width: 200px;
height: 300px;
background: #F80;
}
.notification {
position: fixed;
background: black;
opacity: 0;
color: white;
font-size: 16px;
padding: 0.5em;
right: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.2/isotope.pkgd.js"></script>
<h1>Isotope - layoutComplete</h1>
<p>Open Developer Console to view event logs.</p>
<p>Click item to toggle size</p>
<div class="grid">
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2 grid-item--height2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item grid-item--width2"></div>
<div class="grid-item grid-item--height2"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
<div class="notification"></div>
Upvotes: 0