Meetromb Asked:2020-04-08 11:08:41 +0000 UTC2020-04-08 11:08:41 +0000 UTC 2020-04-08 11:08:41 +0000 UTC 围绕圆定位元素 772 再会。有一个任务: 围绕圆圈排列元素,使它们相互影响,即 如果我们将鼠标悬停在一个元素上,其他元素就会移到一边。 所需结构: <div class="container"> <div class="item"> <div class="item"> <div class="item"> <div class="item"> <div class="item"> </div> javascript 2 个回答 Voted Best Answer Meetromb 2020-04-08T11:08:41Z2020-04-08T11:08:41Z 互联网上有什么? 按度定位元素(不是我们的情况) - https://codepen.io/HugoGiraudel/pen/vEJXGm 均匀分布在整个圆周上。该选项很有趣,但不依赖于元素的大小 - https://codepen.io/pat_hg/pen/JYEZMe?limit=all&page=3&q=circle 属性shape-outside,仅适用于文本(根本不适用) - https://css-tricks.com/almanac/properties/s/shape-outside/ 如何实施? 我们确定我们的元素将占据的扇区的角落。我在和弦上做了计算,和弦也需要计算,因为 它只是радиус * 2行不通 - 元素之间会有差异。 将角与元素的中心相加 计算圆上的一个点并将坐标分配给一个元素 现在我们需要计算与元素交互时的角度: 悬停时,您可以更改任何内容,但对我们来说主要作用是size。我们将新的大小写入缓冲区或元素的属性并重新计算位置 好的,改变元素的角度是根据旧公式计算的,它们相应变大,元素向右移动。 但是如果你想让元素在两边移动,那么你需要将之前的(初始)大小值写入缓冲区,然后计算差异并将每个元素的角度减少到改变元素角度的一半。 带注释的工作代码: var container = $('.container'); var radius = $('.container').height() / 2; var item = $('.item'); var leftAngle = 0; //start angle var angle = -Math.PI / 2; // 90 deg //angle steps between elements var step = Math.PI / 12; //15 deg var multiplier = 1; function calcPositions() { //calculate left rotation angle item.each(function() { //difference in sizes if item hovered var sizesDiff = $(this).attr('data-width') - $(this).attr('data-before'); //if sizes are different, calc angle to rotate items to left if(sizesDiff != 0 && leftAngle == 0) { leftAngle = angleByChord($(this).attr('data-width') / 2, radius) / 4; } }); //rotate items to left if(leftAngle != 0) { angle -= leftAngle; } leftAngle = 0; item.each(function(index) { //if first, no rotation if(index == 0) { multiplier = 0; } else { multiplier = 1; } //get container circle section angle var thisItemAngleSection = angleByChord($(this).attr('data-width') / 2, radius); //this aitem angle rotation angle += ((thisItemAngleSection / 2) + step) * multiplier; //calculate positions var posX = radius + radius * Math.cos(angle); var posY = radius + radius * Math.sin(angle); //set half of angle to next element multiplier = 1 angle += ((thisItemAngleSection / 2) + step) * multiplier; $(this).css({ left: posX + 'px', top: posY + 'px' }); }); //reset angle = -Math.PI / 2; } //get angle of item function angleByChord(this_radius, radius) { var a = (2*radius*radius - this_radius*this_radius) / (2 * radius); var chord = Math.sqrt(radius*radius - a*a) * 2; return Math.asin(chord / (2 * radius)) * 2; } /* actions */ $('.start').on('click', function() { calcPositions(); }); $('.item').hover(function() { $(this).attr('data-before', $(this).width()); $(this).addClass('big'); //update final widths (after transitions) $(this).attr('data-width', getFinalWidthOfElement($(this))); //recalsulate positions calcPositions(); }, function() { $(this).removeClass('big'); //return widths $(this).attr('data-width', 30);//getFinalWidthOfElement($(this))); $(this).attr('data-before', 30);//$(this).width()); calcPositions(); leftAngle = 0; }); function getFinalWidthOfElement(element) { //clone current elem var clone = element.clone(); //remove transitions to get final sizes clone.css('transition', 'none'); //hide and change classes clone.hide(); clone.removeClass('item'); element.parent().append(clone); //our final sizes of item var endHeight = clone.height(); //remove because we're already get sizes clone.remove(); return endHeight; } .container { position: relative; margin-top: 50px; margin-left: 100px; height: 200px; width: 200px; border-radius: 50%; border: 1px solid #000; } .item { position: absolute; height: 30px; width: 30px; top: 100px; left: 100px; border-radius: 50%; background: red; line-height: 30px; color: #fff; font-family: sans-serif; text-align: center; transform: translateX(-50%) translateY(-50%); cursor: pointer; transition: all 0.3s ease-in-out; } .big { background: orange; height: 60px; width: 60px; line-height: 60px; } .start { display: inline-block; background: #cccc; padding: 10px 25px; border: 1px solid #000; font-family: sans-serif; cursor: pointer; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="start">Start</div> <div class="container"> <div class="item" data-width="30" data-before="30">1</div> <div class="item" data-width="30" data-before="30">2</div> <div class="item" data-width="30" data-before="30">3</div> <div class="item" data-width="30" data-before="30">4</div> <div class="item" data-width="30" data-before="30">5</div> </div> 如需改进:https ://codepen.io/meetromb/pen/LdXgNd user33274 2020-04-08T14:38:15Z2020-04-08T14:38:15Z 当然,这根本不是菜单,只是碰巧是这样做的,但你可以修改它,它会是你需要的: *{ margin:0; padding:0; box-sizing:border-box; transition:all .5s .3s cubic-bezier(0.08, 0.81, 0.58, 0.01); } .items{ width:300px; height:300px; margin:80px auto; position:relative; border-radius: 50%; background:#fbfbfb; } .cord, .item{ position: absolute; top:50%; left:50%; width:2px; height:2px; background:#ccc; margin:-1px; overflow:hidden; } .items:hover .cord{ width:100px; height:100px; border-radius:50%; position: absolute; left:calc(100% - 50px); top:calc(50% - 50px); } .items:hover .item1{ width:100px; height:100px; border-radius:50%; position: absolute; left:calc(85% - 50px); top:calc(15% - 50px); transition-delay: 0.1s; animation-delay:0.1s; } .items:hover .item2{ width:100px; height:100px; border-radius:50%; position: absolute; left:90px; top:-40px; transition-delay: 0.2s; animation-delay:0.2s; } .items:hover .item3{ width:100px; height:100px; border-radius:50%; position: absolute; left:-20px; top:5px; transition-delay: 0.3s; animation-delay:0.3s; } .items:hover .item4{ width:100px; height:100px; border-radius:50%; position: absolute; left:-45px; top:115px; transition-delay: 0.4s; animation-delay:0.4s; } .items:hover .item5{ width:100px; height:100px; border-radius:50%; position: absolute; left:25px; top:215px; transition-delay: 0.5s; animation-delay:0.5s; } .item{ visibility: hidden; opacity:0; } .items:hover .cords, .items:hover .item{ visibility: visible; opacity:1; animation:scale .5s .3s cubic-bezier(0, 1, 0.92, 0.11); } @keyframes scale{ 100%{ transform:scale(.3)rotate(360deg); background:#fbfbfb; } } <div class="items"> <div class="item item1"></div> <div class="item item2"></div> <div class="item item3"></div> <div class="item item4"></div> <div class="item item5"></div> <div class="cord"></div> </div>
互联网上有什么?
shape-outside,仅适用于文本(根本不适用) - https://css-tricks.com/almanac/properties/s/shape-outside/如何实施?
радиус * 2行不通 - 元素之间会有差异。现在我们需要计算与元素交互时的角度:
悬停时,您可以更改任何内容,但对我们来说主要作用是size。我们将新的大小写入缓冲区或元素的属性并重新计算位置
好的,改变元素的角度是根据旧公式计算的,它们相应变大,元素向右移动。
但是如果你想让元素在两边移动,那么你需要将之前的(初始)大小值写入缓冲区,然后计算差异并将每个元素的角度减少到改变元素角度的一半。
带注释的工作代码:
如需改进:https ://codepen.io/meetromb/pen/LdXgNd
当然,这根本不是菜单,只是碰巧是这样做的,但你可以修改它,它会是你需要的: