问题
I'm trying to generate a 'nice' CSS menu using (mainly) CSS, but with a tiny bit of jQuery as well:
My overall idea is:
+------------------------+
| |
| |
| +---+ |
| | | |
| |___| | <-- Hover this center piece
| |
| |
| |
+------------------------+
+------------------------+
| _ |
| |\ | <-- All start moving up to top of screen
| \ +---+ |
| | | |
| |___| |
| |
| |
| |
+------------------------+
+------------------------+
| +---+ |
| | | |
| |___| |
| |
| || All, but one |
| || moves down |
| \/ |
| |
+------------------------+
+------------------------+
| +---+ |
| | | |
| |___| |
| |
| One stays, |
| +---+ the rest move this way
| | | ---> |
| |___| |
+------------------------+
+------------------------+
| +---+ |
| | | |
| |___| ^ | The rest move up
| | |
| | |
| +---+ +---+ |
| | | | | |
| |___| |___| |<-- Another stays
+------------------------+
Complete:
+------------------------+
| +---+ +---+ |
| | 1 | | 4 | |
| |___| |___| |
| |
| |
| +---+ +---+ |
| | 2 | | 3 | |
| |___| |___| |
+------------------------+
However, that presumes that there will be four div children, So I'm trying to generate a way of 'determining the angle/position' in jQuery (which, to be honest, isn't working too well).
Similar design:

So in the end, since there are four divs, they will be at 90 degree intervals from the center (360/4 divs = 90 degrees apart).
If there were, say, six child divs;
360/6 = 60 degrees
So they will be evenly spaced out at 60 degree intervals.
I'll be adding animation as well between them, so hence why I've been playing about with rotations, etc., but I just can't seem to get to grips with it:
My current sample is:
$(".wrap").hover(function(){
var x =$(this).children().length; //Counts '.circles'
var degree = 360 / x; //Gets angle
var percent = 100 / x;
var curPercent = percent;
$(this).children().each(function (index) {
$(this).css("transform","rotate(" + degree*index + "deg)");
$(this).css("top",percent + "px");
$(this).css("left",percent + "px");
percent = percent + curPercent;
});
});
.wrap{
height: 300px;
width: 300px;
background: red;
position: relative;
transform-origin: center center;
transition: all 0.8s;
}
.wrap:hover .circle{
top: 0;
left: 0;
}
.circle{
transition: all 0.8s;
position: absolute;
height: 50px;
width: 50px;
top: calc(50% - 25px);
left: calc(50% - 25px);
background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="circle">1</div>
<div class="circle">2</div>
<div class="circle">3</div>
<div class="circle">4</div>
</div>
Fiddle
Would anyone:
(A): Know how to get the divs to 'rotate' the specified angle or distance in relevance to the parent specified in the jQuery code?
(B): Get the 'animation' to reset on hover out?
- (C):
Have any idea what I'm talking about?
Similar implementations (although not exact):
- Here
- This more so - but this uses Sass (not wanted)
回答1:
Using a different approach you'll get a slightly different effect. You can play with the times of the setTimeout
and the transition
to modify the behavior.
See the fiddle
+ function() {
var to;
$(".wrap").on('mouseenter', function() {
var circles = $(this).children();
var degree = (2 * Math.PI) / circles.length; //calc delta angle
var transforms = [];
// Calculate the position for each circle
circles.each(function(index) {
var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));
transforms.push('translate(' + x + 'px,' + y + 'px)');
});
// Function to moves all the circles
// We'll pop a circle each time and than call this function recursively
function moveCircles() {
var transform = transforms.shift();
circles.css('transform', transform);
circles.splice(0, 1);
if (circles.length) to = setTimeout(moveCircles, 400);
}
moveCircles();
});
$(".wrap").on('mouseleave', function() {
var circles = $(this).children().css('transform', '');
clearTimeout(to);
});
}();
.wrap {
height: 300px;
width: 300px;
background: red;
position: relative;
transform-origin: center center;
transition: all 0.8s;
}
.circle {
transition: all 0.8s;
position: absolute;
height: 50px;
width: 50px;
text-align: center;
line-height: 50px;
top: calc(50% - 25px);
left: calc(50% - 25px);
background: tomato;
border-radius: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="circle">1</div>
<div class="circle">2</div>
<div class="circle">3</div>
<div class="circle">4</div>
<div class="circle">5</div>
<div class="circle">6</div>
</div>
回答2:
function rotateStep($this, $circle, angle) {
$this.animate({
rotation: angle
}, {
step: function(now, fx) {
$this.css({
transform: 'rotate(' + now + 'deg)'
});
$circle.css({
transform: 'translate(-50%, -50%) rotate(' + -now + 'deg)'
});
}
});
}
$('.wrap').hover(function() {
var $this = $(this),
$circleWrappers = $this.find('.circleWrapper'),
angleOffset = 360 / $circleWrappers.length,
angle = - angleOffset / 2,
distance = Math.min($this.width(), $this.height()) / 2;
$circleWrappers.each(function() {
var $this = $(this),
$circle = $(this).find('.circle');
$circle.animate({ top: -distance });
rotateStep($this, $circle, angle);
angle -= angleOffset;
});
}, function() {
var $this = $(this),
$circleWrappers = $this.find('.circleWrapper');
$circleWrappers.each(function() {
var $this = $(this),
$circle = $(this).find('.circle');
$circle.animate({ top: 0 });
rotateStep($this, $circle, 0);
});
});
.wrap {
position: relative;
background-color: #cccccc;
width: 400px;
height: 400px;
transition:all 0.8s;
transform-origin: center center;
}
.circleWrapper {
display: inline-block;
position: absolute;
left: 50%;
top: 50%;
}
.circle {
position: absolute;
width: 80px;
height: 80px;
border-radius: 40px;
background-color: white;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
line-height: 80px;
text-align: center;
font-family: arial;
font-size: 42px;
font-weight: bold;
transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
<div class="circleWrapper"><div class="circle">1</div></div>
<div class="circleWrapper"><div class="circle">2</div></div>
<div class="circleWrapper"><div class="circle">3</div></div>
<div class="circleWrapper"><div class="circle">4</div></div>
</div>
JSFiddle
来源:https://stackoverflow.com/questions/28497425/creating-a-css-path-on-hover