Reputation: 5119
I'm trying to do a 3d mouseover effect when you're over a DIV. Here's what it's look like for now
I would like to know how I could make in sort that the lower-left and top-right corner would have a cleaner shadow, oblique style. I thought maybe load a triangle on those corners but I would like to know if there's any other way I could achieve that.
Thanks
Upvotes: 3
Views: 1228
Reputation: 49198
I thought it would be fun to try the "blocklets" approach, ie, use div
s to create the appearance of 3D by layering div
s between the background and the box, with the in-betweens being offset from the parent by one pixel top and left to create the appearance of depth.
Note, I'm not suggesting this a great approach, as a number of issues could impact performance. However, I was pleasantly surprised to see that I could get relatively good performance with the below code, and yes, it appears to work (as-is) in IE7/8/9, as well as FF10 and Chrome 17.
So if it's useful to you, I'm glad to hear that, although I would hasten to add it's really just a jumping-off/starting point. There are some known issues I have observed, such as multiple boxes cause the animation to kind've fall apart. But it appears to work alright with a single box, and I imagine with some work it could be made to work better, and could even be ported to a plugin (if someone so desired).
Let me know if you have any questions or if you see anything that can/should be fixed, or if you think it's stupid/pointless/just turrible and can explain why.
HTML
Basic markup:
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
CSS
I added the borders because I thought it looked better:
.shadow {
position: relative;
float: left;
}
.threed {
background: black;
position: absolute;
top: 0;
left: 0;
}
.box {
width: 298px;
height: 298px;
background: #cacaca;
position: relative;
border: 1px solid #aaa;
border-left: 1px solid #acacac;
border-top: 1px solid #acacac;
}
jQuery
$(function(){
var $threed = $('<div class="threed">'),
$shadow = $('<div class="shadow">'),
offset = 0;
var init = function($jq, distance, speed){
$jq.each(function(){
var $this = $(this),
$threeds,
$shadow_clone = $shadow.clone(),
$threed_clone,
borderlw = parseInt($this.css('border-left-width')),
borderrw = parseInt($this.css('border-right-width')),
bordertw = parseInt($this.css('border-top-width')),
borderbw = parseInt($this.css('border-bottom-width')),
width = parseInt($this.innerWidth()) + borderlw + borderrw,
height = parseInt($this.innerHeight()) + bordertw + borderbw,
dimensions = {height: height, width: width};
$shadow_clone.css({
height: height + distance,
width: width + distance}
);
$this.data('distance', distance).wrap($shadow_clone);
for (var i = 0; i <= distance; i++) {
var $threed_clone = $threed.clone();
$this.before($threed_clone);
$threed_clone.css(dimensions).data('dimensions', {
left: i, top: i
});
}
$this.data('threeds', $this.siblings('.threed'));
$this.mouseenter(function(){
var offset = 0,
properties = {
left: distance,
top: distance
},
options = {
duration: speed,
step: goUp,
complete: finishThreeD
};
$(this).stop().animate(properties, options);
})
.mouseleave(function(){
var properties = {
left: 0,
top: 0
},
options = {
duration: speed,
step: goDown,
complete: finishTwoD
};
$(this).stop().animate(properties, options);
});
});
};
var goUp = function(){
var _offset = parseInt(this.style.left);
if (_offset > offset) {
offset = _offset;
$($(this).data().threeds[offset - 1])
.prevAll('.threed').each(function(){
$(this).css($(this).data().dimensions);
});
}
};
var finishThreeD = function() {
$(this).data().threeds.each(function(){
$(this).css($(this).data().dimensions);
});
};
var goDown = function (){
var _offset = parseInt(this.style.left);
if (_offset < offset) {
offset = _offset;
$($(this).data().threeds[offset - 1])
.nextAll('.threed').css({top: 0, left: 0});
if (offset === 0) {
$(this).data().threeds.css({top: 0, left: 0});
}
}
};
var finishTwoD = function (){
$(this).data().threeds.css({top: 0, left: 0});
offset = 0;
};
var inc = 1;
$('.box').each(function(){
init($(this), 10 * inc, 100 * (2.5 * inc));
inc++;
});
});
Upvotes: 1
Reputation: 253318
If you don't mind using pseudo-elements, there's the ::before
and ::after
(although note that, as I recall, IE doesn't recognise the double-colon declaration, so you'd really have to use :before
and :after
):
#box::before {
content: ' ';
position: absolute;
top: -10px;
left: -10px;
bottom: 0;
height: 100%;
background-color: #f90;
border-bottom: 10px solid white;
border-right: 10px solid black;
}
#box::after {
content: ' ';
position: absolute;
top: -10px;
left: -10px;
right: 0;
width: 100%;
border-bottom: 10px solid black;
border-right: 10px solid white;
}
Upvotes: 3