Reputation: 15003
I have a grid of 6 blocks. When clicking on each of the block, the block expand and cover the container holding the blocks.
The first box (top left) looks fine, but the others fail the illusion that the block grows to the container width and height, because it starts from their top left position.
Ideally box 2 and 5 should expand from their center and box 1, 3, 4 and 6 should expand from their far corners. Is that possible and how?
I've created a JSFiddle that shows my problem. But the code for reproduce is here:
JQuery
$(".service-block").on("click", "a", function (e) {
e.preventDefault();
var block = $(this);
var blockOffset = block.offset();
var blockBackgroundColor = block.css("backgroundColor");
var container = $(".service-grid");
var containerOffset = container.offset();
// Create the popup and append it to the container
var popout = $("<div class='service-block-popup'>Test</div>");
popout.css({
"backgroundColor": blockBackgroundColor,
"position": "absolute",
"top": blockOffset.top,
"left": blockOffset.left
}).appendTo(container)
// Now animate the properties
.animate({
"height": container.height() + "px",
"width": container.width() + "px",
"top": containerOffset.top,
"left": containerOffset.left
}, 1500, function() {
//alert("done");
})
.on("click", function () {
popout.remove();
});
});
Markup
<div class="service-grid">
<div class="row">
<div class="service-block">
<a href="#" class="box1">
<span class="title">Box 1</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box2">
<span class="title">Box 2</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box3">
<span class="title">Box 3</span>
</a>
</div>
</div>
<div class="row">
<div class="service-block">
<a href="#" class="box4">
<span class="title">Box 4</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box5">
<span class="title">Box 5</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box6">
<span class="title">Box 6</span>
</a>
</div>
</div>
</div>
CSS
*, *::after, *::before {
box-sizing: border-box;
}
.service-grid { width: 600px; }
.row {
overflow: hidden;
}
.service-grid .service-block a {
display: block;
height: 200px;
width: 200px;
text-align: center;
float: left;
}
.service-grid .service-block a > img {
display: block;
margin: 0 auto;
transition: all 100ms linear 0s;
}
.service-grid .service-block a > .title {
display: block;
font-family: Arial,Helvetica,sans-serif;
font-size: 2.2rem;
font-weight: bold;
line-height: 3.2rem;
margin-top: 20px;
text-transform: uppercase;
}
.box1 { background: red; }
.box2 { background: purple; }
.box3 { background: yellow; }
.box4 { background: orange; }
.box5 { background: green; }
.box6 { background: magenta; }
Upvotes: 6
Views: 236
Reputation: 199
Understood that classes weren't your preference, but they are the most efficient approach, in regards to both memory and animation smoothness.
Applying the starting value(s) (Eg. width/height/etc.)
, animation-settings
and scale(0)
on the base-class (.message
) is required.
HTML
<div class="trigger">trigger</div>
<div class="message">XXXXXXXXXhXXXXXX</div>
CSS
.message{
background-color: blue;
transform: scale(0);
transform-origin: top left;
height: 100px;
transition: width 2s, height 2s, transform 2s;
}
.unreadMessage{
transform: scale(1);
}
jQuery
var msg = $('.message'),
trigger = $('.trigger')
trigger.on('click',function(){
msg.toggleClass('unreadMessage')
})
Codepen Example: https://codepen.io/gavAusMac/pen/zYKgWJN
Bonus Info: - Also, if applying dynamic style changes (eg. width/height) via Javascript
, the use of requestAnimationFrame()
& setTimeout()
combined may be required, to ensure that dynamic height/etc. are applied before the animation class is set.
Code Example:
$(msg).css('width', dynamicWidth + 'px')
$(msg).css('height', dynamicHeight + 'px')
requestAnimationFrame(function() {
setTimeout(function() {
$(msg).toggleClass('unreadMessage')
});
});
Upvotes: 0
Reputation: 1927
I've generated dynamic top and left based on width/height of container and width/height of box. Based on what size of container and box is, it will decide the position of box, whether it is in corner or in center and then decide top and left.
Here is js code :
$(".service-block").on("click", "a", function (e) {
e.preventDefault();
var block = $(this);
var blockOffset = block.offset();
var blockBackgroundColor = block.css("backgroundColor");
var container = $(".service-grid");
var containerOffset = container.offset();
var top = 0;
var left = 0;
if (blockOffset.top - containerOffset.top == 0 && blockOffset.left - containerOffset.left == 0) {
top = blockOffset.top;
left = blockOffset.left;
} else if (blockOffset.top - containerOffset.top == 0 && blockOffset.left - containerOffset.left + block.width() == container.width()) {
top = blockOffset.top;
left = container.width() - containerOffset.left;
} else if (blockOffset.top - containerOffset.top + block.height() == container.height() && blockOffset.left - containerOffset.left == 0) {
top = container.height() - containerOffset.top;
left = containerOffset.left;
} else if (blockOffset.top - containerOffset.top + block.height() == container.height() && blockOffset.left - containerOffset.left + block.width() == container.width()) {
top = container.height() - containerOffset.top;
left = container.width() - containerOffset.left;
} else {
top = blockOffset.top + (block.width() / 2);
left = blockOffset.left + (block.height() / 2);
}
// Create the popup and append it to the container
var popout = $("<div class='service-block-popup'>Test</div>");
popout.css({
"backgroundColor": blockBackgroundColor,
"position": "absolute",
"top": top,
"left": left
}).appendTo(container)
// Now animate the properties
.animate({
"height": container.height() + "px",
"width": container.width() + "px",
"top": containerOffset.top,
"left": containerOffset.left
}, 1500, function() {
//alert("done");
})
.on("click", function () {
popout.remove();
});
});
Here is fiddle.
It will work for more than 6 boxes.
Upvotes: 1
Reputation: 15003
I am going to answer my question myself. This was a simple mistake!
I did not set the width/height on the .service-block-popup
. So it did not expand from its current state. This is how it should be constructed:
// Create the popup and append it to the container
var popout = $("<div class='service-block-popup'>Test</div>");
popout.css({
"backgroundColor": blockBackgroundColor,
"position": "absolute",
"top": blockOffset.top,
"left": blockOffset.left,
"width": block.outerWidth(),
"height": block.outerHeight()
}).appendTo(container)
/* .... */
Here in action: http://jsfiddle.net/hdq0x2s8/4/
Upvotes: 1
Reputation: 14149
Try This code I have Some change CSS & JS
$(".service-block").on("click", "a", function (e) {
e.preventDefault();
var block = $(this);
var blockOffset = block.offset();
var blockBackgroundColor = block.css("backgroundColor");
var container = $(".service-grid");
var containerOffset = container.offset();
// Create the popup and append it to the container
var popout = $("<div class='service-block-popup'>Test</div>");
popout.css({
"backgroundColor": blockBackgroundColor,
"position": "absolute",
"left": "50%",
"top": "50%",
}).appendTo(container)
// Now animate the properties
.animate({
"height": container.height() + "px",
"width": container.width() + "px",
"top": containerOffset.top,
"left": containerOffset.left
}, 1500, function () {
//alert("done");
})
.on("click", function () {
popout.remove();
});
});
Demo Link http://jsfiddle.net/hdq0x2s8/3/
Upvotes: 0
Reputation: 1530
Hope this code will useful for you, I just added a few line of code. Find fiddle here
$(".service-block").on("click", "a", function (e) {
e.preventDefault();
var block = $(this);
var blockOffset = block.offset();
var blockBackgroundColor = block.css("backgroundColor");
var container = $(".service-grid");
var containerOffset = container.offset();
// Create the popup and append it to the container
var popout = $("<div class='service-block-popup'>Test</div>");
thisHeight = $(this).height();
thisWidth = $(this).height();
var clsName = $(this).attr('class');
var topEle = ["box1", "box2", "box3"];
if ($.inArray(clsName, topEle) > -1)
{
thisHeight = 0;
}
var leftEle = ["box1", "box4"];
if ($.inArray(clsName, leftEle) > -1)
{
thisWidth = 0;
}
var midEle = ["box2", "box5"];
if ($.inArray(clsName, midEle) > -1)
{
thisWidth = thisWidth/2;
}
popout.css({
"backgroundColor": blockBackgroundColor,
"position": "absolute",
"top": blockOffset.top + thisHeight,
"left": blockOffset.left + thisWidth
}).appendTo(container)
// Now animate the properties
.animate({
"height": container.height() + "px",
"width": container.width() + "px",
"top": containerOffset.top,
"left": containerOffset.left
}, 1500, function() {
//alert("done");
})
.on("click", function () {
popout.remove();
});
});
*, *::after, *::before {
box-sizing: border-box;
}
.service-grid { width: 600px; }
.row {
overflow: hidden;
}
.service-grid .service-block a {
display: block;
height: 200px;
width: 200px;
text-align: center;
float: left;
}
.service-grid .service-block a > img {
display: block;
margin: 0 auto;
transition: all 100ms linear 0s;
}
.service-grid .service-block a > .title {
display: block;
font-family: Arial,Helvetica,sans-serif;
font-size: 2.2rem;
font-weight: bold;
line-height: 3.2rem;
margin-top: 20px;
text-transform: uppercase;
}
.box1 { background: red; }
.box2 { background: purple; }
.box3 { background: yellow; }
.box4 { background: orange; }
.box5 { background: green; }
.box6 { background: magenta; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="service-grid">
<div class="row">
<div class="service-block">
<a href="#" class="box1">
<span class="title">Box 1</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box2">
<span class="title">Box 2</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box3">
<span class="title">Box 3</span>
</a>
</div>
</div>
<div class="row">
<div class="service-block">
<a href="#" class="box4">
<span class="title">Box 4</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box5">
<span class="title">Box 5</span>
</a>
</div>
<div class="service-block">
<a href="#" class="box6">
<span class="title">Box 6</span>
</a>
</div>
</div>
</div>
Upvotes: 0