我正在尝试使用Vanilla、CSS和HTML构建一个导航用户界面,并被困在需要上下移动div元素并根据它们的cureent状态active或inactive更改其顶部和右边位置的位置上。
const diamond = document.getElementById('main-diamond'),
pointerArrowTop = document.getElementById('pointer-arrow-top'),
pointerArrowRight = document.getElementById('pointer-arrow-right'),
pointerArrowBottom = document.getElementById('pointer-arrow-bottom'),
pointerArrowLeft = document.getElementById('pointer-arrow-left'),
mouseoverEvent = new Event('mouseover'),
radius = 200, // The radius of the semi circle
nodes = document.querySelectorAll('[data-first]'), // number of nodes in the code
nodeContainerFirst = document.querySelector('[data-node-level="first"]'), // Get the container of the first level nodes
nodeWidth = nodes[0].clientWidth, // Defined width of the node
nodeHeight = nodes[0].clientHeight, // Defined width of the node
angle = Math.round( 180 / (nodes.length - 1)); // Distance of the gap between nodes;
pointerArrowTop.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowTop.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
diamond.style.transform = "rotate(45deg)";
});
pointerArrowTop.addEventListener('click', function(e){
let activeNode = document.querySelector('[data-state="active"]'),
inactiveNodes = document.querySelectorAll('[data-state="inactive"]'),
siblingNode = activeNode.nextElementSibling,
previousSiblingNode = activeNode.previousElementSibling;
activeNode.setAttribute('style', 'top: -180px; left: -40px');
activeNode.dataset.state = 'inactive';
siblingNode.setAttribute('style', 'top: -180px; left: 0px;');
siblingNode.dataset.state = 'active';
inactiveNodes.forEach(function(node, index){
if(previousSiblingNode){
if(index != 2 && index != 0 && index != 1){
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+((index+1)+180 *(index))+'px;');
}
}else{
if(index != 0){
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+((index+1)+180*(index))+'px;');
}
}
});
});
pointerArrowRight.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowRight.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowBottom.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowBottom.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowLeft.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowLeft.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
document.addEventListener("DOMContentLoaded", function() {
nodes.forEach(function(node, index) {
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+(index+1)+'px;');
});
});@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
body {
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
font-family: 'Montserrat', sans-serif;
}
body.dark-mode {
background: linear-gradient(to bottom right,#15071a,#1a0f29,#1c2b3f,#064a5b) #f7f7f7;
color: #f7f7f7;
}
.d-flex-center {
display: flex;
align-items: center;
}
.centerPointMarker {
position: absolute;
width: 10px;
height: 10px;
background-color: aqua;
border-radius: 50%;
}
.app-container {
width: calc(100% - 34px);
max-width: 960px;
height: 100vh;
margin: 0px 17px;
}
header {
height: 100px;
width: 100%;
display: block;
margin-bottom: 20px;
}
.p-t-180 {
padding-top: 180px;
}
main {
display: block;
overflow-y: hidden;
max-height: 700px;
}
.nav-container {
width: 114px;
height: 180px;
display: flex;
align-items: center;
}
.nav-container #main-diamond {
width: 83px;
height: 83px;
border: 1px solid #fff;
border-radius: 12px;
background-color: #000;
transform: rotate(45deg);
position: relative;
margin-left: 14px;
margin-top: 16px;
margin-bottom: 16px;
transition: all 300ms ease-in-out;
shape-outside: circle();
}
.nav-container #main-diamond .controls-container {
position: relative;
transform: rotate(-45deg);
width: 147px;
height: 147px;
left: -22px;
top: -22px;
}
.nav-container #main-diamond .controls-container .pointer-arrow {
font-size: 8px;
position: absolute;
color: #6A696D;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top {
left: 69px;
top: 13px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover {
cursor: pointer;
transform: scale(1.5);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover ~ .center-icon {
border-top-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right {
transform: rotate(90deg);
right: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover {
cursor: pointer;
transform: scale(1.5) rotate(90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover ~ .center-icon {
border-right-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom {
transform: rotate(180deg);
left: 69px;
bottom: 45px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover {
cursor: pointer;
transform: scale(1.5) rotate(180deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover ~ .center-icon {
border-bottom-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left {
transform: rotate(-90deg);
left: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover {
cursor: pointer;
transform: scale(1.5) rotate(-90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover ~ .center-icon {
border-left-color: #FFF;
}
.nav-container #main-diamond .controls-container .center-icon {
width: 59px;
height: 59px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid #6A696D;
border-radius: 50%;
position: absolute;
left: 44px;
top: 28px;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .center-icon i {
font-size: 26px;
position: relative;
top: 1px;
}
.node-container {
display: block;
position: relative;
width: 342px;
height: 181px;
opacity: 1;
padding: 20px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
.node-container .node-inner-container {
position: relative;
height: 100%;
}
.node-container .node-inner-container svg.level-diamond {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
float: left;
}
.node-container .node-inner-container .node-text {
width: calc(100% - 50px);
margin-left: 50px;
}
span.node-level-counter {
position: absolute;
bottom: -5px;
right: 0px;
font-weight: 200;
font-size: 12px;
}
svg.level-diamond rect.first-level {
fill: #F6AE3C;
}
svg.level-diamond text.first-level {
font-size: 20px;
font-weight: 600;
}
svg.level-diamond rect.second-level {
fill: #69C3C6;
}
svg.level-diamond text.second-level {
font-size: 18px;
font-weight: 500;
}
svg.level-diamond rect.third-level {
fill: #6DBD50;
}
svg.level-diamond text.third-level {
font-size: 16px;
font-weight: 500;
}
svg.level-diamond rect.fourth-level {
fill: #E4087D;
}
svg.level-diamond text.fourth-level {
font-size: 14px;
font-weight: 500;
}
footer {
height: 60px;
width: 100%;
display: block;
margin-top: 20px;
}
.semicircle {
position: absolute;
width: 52px;
height: 52px;
}<script src="https://kit.fontawesome.com/a8d572acbe.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<body class="dark-mode">
<header></header>
<main>
<div class="container">
<div class="row">
<div class="col-2 p-t-180">
<div class="nav-container">
<div id="main-diamond" style="z-index: 200;">
<div class="controls-container">
<div class="pointer-arrow top" id="pointer-arrow-top"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow right" id="pointer-arrow-right"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow bottom" id="pointer-arrow-bottom"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow left" id="pointer-arrow-left"><i class="fas fa-triangle"></i></div>
<div class="center-icon">
<i class="fad fa-fingerprint"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-4 pl-1 p-t-180">
<div class="node-container" data-first data-state="active" data-node-number="1">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-1"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">1</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 1 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="2">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-2"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">2</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 2 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="3">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-3"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">3</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 3 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="4">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-4"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">4</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 4 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="5">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-5"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">5</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 5 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="6">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-6"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">6</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 6 of 6</span>
</div>
</div>
</div>
</div>
</div>
</main>
<footer></footer>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/app.js"></script>
</body>
正如您从上面的示例中可以看到,当用户单击向上箭头时,第一个节点移动到它应该选择的位置,但是节点3-6堆栈在彼此之上,单击向上箭头时,应该再次级联节点3,将焦点集中在中间,而节点2将定位于上面的left: -40px,而节点1位于上面的节点1上,使用left: -80px。
我想不出该如何正确地做这件事,而且已经走了许多死胡同。
我使用,因为这个项目不支持jQuery。任何帮助都是很好的,谢谢!
发布于 2020-03-29 07:20:11
问题
你的解决方案几乎是正确的。您的问题在于position: relative和top值的调整。在pointer-arrow-top的第一次单击中,您将调整以下活动节点元素的顶部值,使其成为-180 +索引(-180px、-361px等)的乘数。在进一步探讨这个问题之前,我建议重新讨论position: relative的概念。
当您调整相对定位元素的顶部值时,元素是可视从其实际位置移动。浏览器仍然跟踪元素的实际位置。然后,下一个兄弟姐妹也根据上一个元素的实际位置(视觉移动之前的位置)而不是视觉上的位置来放置。这是一张图片来展示我的意思。我还建议阅读 on MDN一节。

这就是为什么当您的第一个元素的最高值被调整为-180 it,而您的第二个元素的最高值被调整为-180 it时,它可以工作。但是,第三个元素的最高值调整到-182 to,第四个元素的最高值调整到-363 to,导致它们重叠。想想看:-180 of意味着上升一级。当您将第四个元素的最高值调整为-363 to时,将使其上升两个级别;从而使其处于与第三个元素相同的级别(同样的逻辑适用于第五个和第六个元素)。我们想要的是,每次单击顶部箭头时,调整每个元素,使其上升一个级别。
现在,很明显,我们可以通过调整所有元素,使其每一次点击一个级别,然后根据索引添加一些额外的顶级值来解决这个问题。
解决方案
如前所述,我们不需要调整顶部的值乘以索引。相反,所有元素的顶部值都需要相同。这是一个可行的解决方案。与代码的主要区别(使其按预期工作)是在click侦听器上。请尝试运行它;-)我添加了一个data-node-position的数据属性,以跟踪我应该给每个元素多少最高值。
const diamond = document.getElementById('main-diamond'),
pointerArrowTop = document.getElementById('pointer-arrow-top'),
pointerArrowRight = document.getElementById('pointer-arrow-right'),
pointerArrowBottom = document.getElementById('pointer-arrow-bottom'),
pointerArrowLeft = document.getElementById('pointer-arrow-left'),
pointerArrows = document.querySelectorAll('.controls-container [class^="pointer-arrow"]'),
mouseoverEvent = new Event('mouseover'),
radius = 200, // The radius of the semi circle
nodes = document.querySelectorAll('[data-first]'), // get all the pillar nodes
nodeContainerFirst = document.querySelector('[data-node-level="first"]'), // Get the container of the first level nodes
nodeWidth = nodes[0].clientWidth, // Defined width of the node
nodeHeight = nodes[0].clientHeight, // Defined width of the node
angle = Math.round(180 / (nodes.length - 1)) // Distance of the gap between nodes;
function initializeNodes() {
nodes.forEach(function(node, index) {
let leftVal = Math.round(index * -40)
let topVal = -1 * (index + 1)
// You should use transform instead of adjusting top and left values
// node.style.transform = `translate(${leftVal}px, ${topVal}px)`
node.style.left = `${leftVal}px`
node.style.top = `${topVal}px`
node.dataset.nodePosition = index + 1
// Limit to two visible nodes on the bottom side
if (node.dataset.nodePosition > 3) node.style.opacity = '0'
})
}
function initializePointerArrowsOnHover() {
const pointerOnHoverBoxShadowValues = {
'top': '-2px -2px 4px rgba(255,255,255,0.4)',
'right': '2px -2px 4px rgba(255,255,255,0.4)',
'bottom': '2px 2px 4px rgba(255,255,255,0.4)',
'left': '-2px 2px 4px rgba(255,255,255,0.4)'
}
pointerArrows.forEach(pointerArrow => {
let pointerDirection
if (pointerArrow.classList.contains('top')) pointerDirection = 'top'
else if (pointerArrow.classList.contains('right')) pointerDirection = 'right'
else if (pointerArrow.classList.contains('bottom')) pointerDirection = 'bottom'
else pointerDirection = 'left'
pointerArrow.addEventListener('mouseover', function(e) {
diamond.style["boxShadow"] = pointerOnHoverBoxShadowValues[pointerDirection]
})
pointerArrow.addEventListener('mouseout', function(e) {
diamond.style["boxShadow"] = null
})
})
}
function initializePointerArrowsOnClick() {
function adjustPositionAndOpacity(clickEvent, direction) {
const activeNode = document.querySelector('[data-state="active"]'),
previousActiveNode = activeNode.previousElementSibling,
nextActiveNode = activeNode.nextElementSibling,
adjustPositionByValue = direction === 'up' ? -1 : 1,
// Top value offset by -180 multiplied by the number of elements on the top side after adjusting position
firstNodePosition = parseInt(nodes[0].dataset.nodePosition),
topValueOffset = Math.abs((firstNodePosition + adjustPositionByValue - 1)) * -180
if (direction === 'up' && !nextActiveNode) return
else if (direction === 'down' && !previousActiveNode) return
nodes.forEach((node, index) => {
let newNodePosition = parseInt(node.dataset.nodePosition) + adjustPositionByValue
node.dataset.nodePosition = newNodePosition
// Adjust opacity for a fade-in fade-out effect
// Some nodes are hidden when there is more than one node on the top side and more than two nodes on the bottom side
if (newNodePosition > 3 || newNodePosition < 0) node.style.opacity = '0'
// Nodes that are hidden are displayed when they are supposed to be visible
else node.style.opacity = '1'
if (newNodePosition === 1) node.dataset.state = 'active'
else node.dataset.state = 'inactive'
const leftValue = Math.abs(newNodePosition - 1) * -40
const topValue = topValueOffset + -1 * newNodePosition
// You should use transform instead of adjusting top and left values
// node.style.transform = `translate(${leftValue}px, ${topValue}px)`
node.style.top = `${topValue}px`
node.style.left = `${leftValue}px`
})
}
pointerArrowTop.addEventListener('click', function(e) {
adjustPositionAndOpacity(e, 'up')
})
pointerArrowBottom.addEventListener('click', function(e) {
adjustPositionAndOpacity(e, 'down')
})
}
document.addEventListener("DOMContentLoaded", function() {
initializeNodes()
initializePointerArrowsOnHover()
initializePointerArrowsOnClick()
})@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
body {
width: 100%;
margin: 0;
padding: 0;
font-family: 'Montserrat', sans-serif;
}
body.dark-mode {
background: linear-gradient(to bottom right, #15071a, #1a0f29, #1c2b3f, #064a5b) #f7f7f7;
color: #f7f7f7;
}
.d-flex-center {
display: flex;
align-items: center;
}
.centerPointMarker {
position: absolute;
width: 10px;
height: 10px;
background-color: aqua;
border-radius: 50%;
}
.app-container {
width: calc(100% - 34px);
max-width: 960px;
height: 100vh;
margin: 0px 17px;
}
header {
height: 100px;
width: 100%;
display: block;
margin-bottom: 20px;
}
.p-t-180 {
padding-top: 180px;
}
main {
display: block;
overflow-y: hidden;
max-height: 700px;
}
.nav-container {
width: 114px;
height: 180px;
display: flex;
align-items: center;
}
.nav-container #main-diamond {
width: 83px;
height: 83px;
border: 1px solid #fff;
border-radius: 12px;
background-color: #000;
transform: rotate(45deg);
position: relative;
/* margin-left: 14px;
margin-top: 16px;
margin-bottom: 16px; */
margin: 14px;
transition: all 300ms ease-in-out;
/* shape-outside: circle(); */
}
.nav-container #main-diamond .controls-container {
position: relative;
transform: rotate(-45deg);
width: 147px;
height: 147px;
left: -22px;
top: -22px;
}
.nav-container #main-diamond .controls-container .pointer-arrow {
font-size: 8px;
position: absolute;
color: #6A696D;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top {
left: 69px;
top: 13px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover {
cursor: pointer;
transform: scale(1.5);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover~.center-icon {
border-top-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right {
transform: rotate(90deg);
right: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover {
cursor: pointer;
transform: scale(1.5) rotate(90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover~.center-icon {
border-right-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom {
transform: rotate(180deg);
left: 69px;
bottom: 45px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover {
cursor: pointer;
transform: scale(1.5) rotate(180deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover~.center-icon {
border-bottom-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left {
transform: rotate(-90deg);
left: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover {
cursor: pointer;
transform: scale(1.5) rotate(-90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover~.center-icon {
border-left-color: #FFF;
}
.nav-container #main-diamond .controls-container .center-icon {
width: 59px;
height: 59px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid #6A696D;
border-radius: 50%;
position: absolute;
left: 44px;
top: 28px;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .center-icon i {
font-size: 26px;
position: relative;
top: 1px;
}
.node-container {
display: block;
position: relative;
width: 342px;
height: 181px;
opacity: 1;
padding: 20px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
transition: top 300ms ease, left 300ms ease, opacity 300ms ease;
/* Use this instead
transition: transform 300ms ease, opacity 300ms ease;
*/
}
.node-container .node-inner-container {
position: relative;
height: 100%;
}
.node-container .node-inner-container svg.level-diamond {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
float: left;
}
.node-container .node-inner-container .node-text {
width: calc(100% - 50px);
margin-left: 50px;
}
span.node-level-counter {
position: absolute;
bottom: -5px;
right: 0px;
font-weight: 200;
font-size: 12px;
}
svg.level-diamond rect.first-level {
fill: #F6AE3C;
}
svg.level-diamond text.first-level {
font-size: 20px;
font-weight: 600;
}
svg.level-diamond rect.second-level {
fill: #69C3C6;
}
svg.level-diamond text.second-level {
font-size: 18px;
font-weight: 500;
}
svg.level-diamond rect.third-level {
fill: #6DBD50;
}
svg.level-diamond text.third-level {
font-size: 16px;
font-weight: 500;
}
svg.level-diamond rect.fourth-level {
fill: #E4087D;
}
svg.level-diamond text.fourth-level {
font-size: 14px;
font-weight: 500;
}
footer {
height: 60px;
width: 100%;
display: block;
margin-top: 20px;
}
.semicircle {
position: absolute;
width: 52px;
height: 52px;
}<script src="https://kit.fontawesome.com/a8d572acbe.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />
<body class="dark-mode">
<header></header>
<main>
<div class="container">
<div class="row">
<div class="col-2 p-t-180">
<div class="nav-container">
<div id="main-diamond">
<div class="controls-container">
<div class="pointer-arrow top" id="pointer-arrow-top"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow right" id="pointer-arrow-right"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow bottom" id="pointer-arrow-bottom"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow left" id="pointer-arrow-left"><i class="fas fa-triangle"></i></div>
<div class="center-icon">
<i class="fad fa-fingerprint"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-4 pl-1 p-t-180">
<div class="node-container" data-first data-state="active" data-node-number="1">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-1"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">1</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 1 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="2">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-2"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">2</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 2 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="3">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-3"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">3</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 3 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="4">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-4"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">4</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 4 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="5">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-5"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">5</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 5 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="6">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-6"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">6</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 6 of 6</span>
</div>
</div>
</div>
</div>
</div>
</main>
<footer></footer>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/app.js"></script>
</body>
个人关切
我在你的代码里看到了一些与我有关的东西。以下是一些:
,
100vw的宽度和100vh的高度。高度(当内容变大时不会膨胀)使你的身体有一个固定的高度,从而导致线性梯度背景重复出现。相反,我已经把你身体的高度调整成自动了。宽度会使水平滚动条出现(因为appearmax-height: 700px值来隐藏溢出的柱柱/节点。当节点内容大小可以使用大量固定像素值changeshape-outside: circle()和z-index: 200在#main-diamond上的内联样式。此外,作为一般的经验规则,避免内联样式,因此CSS更多地不使用JS中的manageableangle、nodeHeight、nodeWidth和nodeContainerFirst。我想,如果您将max-height (从第二点起)调整为基于许多元素乘以max-height,并且在node-container上添加了一些转换,这样导航就不会让mouseover和mouseout事件侦听器“分组”了,这样就更容易阅读了
发布于 2020-03-28 22:14:58
这就是你要找的吗?
function init(){
const diamond = document.getElementById('main-diamond'),
pointerArrowTop = document.getElementById('pointer-arrow-top'),
pointerArrowRight = document.getElementById('pointer-arrow-right'),
pointerArrowBottom = document.getElementById('pointer-arrow-bottom'),
pointerArrowLeft = document.getElementById('pointer-arrow-left'),
mouseoverEvent = new Event('mouseover'),
radius = 200, // The radius of the semi circle
nodes = document.querySelectorAll('[data-first]'), // number of nodes in the code
nodeContainerFirst = document.querySelector('[data-node-level="first"]'), // Get the container of the first level nodes
nodeWidth = nodes[0].clientWidth, // Defined width of the node
nodeHeight = nodes[0].clientHeight, // Defined width of the node
angle = Math.round( 180 / (nodes.length - 1)); // Distance of the gap between nodes;
pointerArrowTop.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowTop.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
diamond.style.transform = "rotate(45deg)";
});
pointerArrowTop.addEventListener('click', function(e){
moveNodes(nodes, 'up');
});
pointerArrowBottom.addEventListener('click', function(e){
moveNodes(nodes, 'down');
});
pointerArrowRight.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowRight.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowBottom.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowBottom.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowLeft.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowLeft.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
}
function moveNodes(nodes, direction){
if((direction=="up" && nodes[5].dataset.index=="0")||(direction=="down" && nodes[0].dataset.index=="0")){return;}
var left, top;
nodes.forEach(function(node, index) {
top = (direction == "up" ? parseInt(node.style.top) - 180 : parseInt(node.style.top) + 180);
left = parseInt(node.style.left);
left = (((node.dataset.index <= 0) && direction=="up") || ((node.dataset.index >= 0) && direction=="down") ? left - 40 : left + 40);
node.dataset.index = (direction=='up' ? parseInt(node.dataset.index) - 1 : parseInt(node.dataset.index) + 1);
node.setAttribute('style', 'left: '+left+'px; top:'+top+'px;');
});
}
window.addEventListener("load", () => { init() }, false);body {
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
font-family: 'Montserrat', sans-serif;
}
body.dark-mode {
background: linear-gradient(to bottom right,#15071a,#1a0f29,#1c2b3f,#064a5b) #f7f7f7;
color: #f7f7f7;
}
.d-flex-center {
display: flex;
align-items: center;
}
.centerPointMarker {
position: absolute;
width: 10px;
height: 10px;
background-color: aqua;
border-radius: 50%;
}
.app-container {
width: calc(100% - 34px);
max-width: 960px;
height: 100vh;
margin: 0px 17px;
}
header {
height: 100px;
width: 100%;
display: block;
margin-bottom: 20px;
}
.p-t-180 {
padding-top: 180px;
}
main {
display: block;
overflow-y: hidden;
/* max-height: 700px; */
}
.nav-container {
width: 114px;
height: 180px;
display: flex;
align-items: center;
}
.nav-container #main-diamond {
width: 83px;
height: 83px;
border: 1px solid #fff;
border-radius: 12px;
background-color: #000;
transform: rotate(45deg);
position: relative;
margin-left: 14px;
margin-top: 16px;
margin-bottom: 16px;
transition: all 300ms ease-in-out;
shape-outside: circle();
}
.nav-container #main-diamond .controls-container {
position: relative;
transform: rotate(-45deg);
width: 147px;
height: 147px;
left: -22px;
top: -22px;
}
.nav-container #main-diamond .controls-container .pointer-arrow {
font-size: 8px;
position: absolute;
color: #6A696D;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top {
left: 69px;
top: 13px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover {
cursor: pointer;
transform: scale(1.5);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover ~ .center-icon {
border-top-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right {
transform: rotate(90deg);
right: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover {
cursor: pointer;
transform: scale(1.5) rotate(90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover ~ .center-icon {
border-right-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom {
transform: rotate(180deg);
left: 69px;
bottom: 45px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover {
cursor: pointer;
transform: scale(1.5) rotate(180deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover ~ .center-icon {
border-bottom-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left {
transform: rotate(-90deg);
left: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover {
cursor: pointer;
transform: scale(1.5) rotate(-90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover ~ .center-icon {
border-left-color: #FFF;
}
.nav-container #main-diamond .controls-container .center-icon {
width: 59px;
height: 59px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid #6A696D;
border-radius: 50%;
position: absolute;
left: 44px;
top: 28px;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .center-icon i {
font-size: 26px;
position: relative;
top: 1px;
}
.node-container {
display: block;
position: relative;
width: 342px;
height: 181px;
opacity: 1;
padding: 20px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
.node-container .node-inner-container {
position: relative;
height: 100%;
}
.node-container .node-inner-container svg.level-diamond {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
float: left;
}
.node-container .node-inner-container .node-text {
width: calc(100% - 50px);
margin-left: 50px;
}
span.node-level-counter {
position: absolute;
bottom: -5px;
right: 0px;
font-weight: 200;
font-size: 12px;
}
svg.level-diamond rect.first-level {
fill: #F6AE3C;
}
svg.level-diamond text.first-level {
font-size: 20px;
font-weight: 600;
}
svg.level-diamond rect.second-level {
fill: #69C3C6;
}
svg.level-diamond text.second-level {
font-size: 18px;
font-weight: 500;
}
svg.level-diamond rect.third-level {
fill: #6DBD50;
}
svg.level-diamond text.third-level {
font-size: 16px;
font-weight: 500;
}
svg.level-diamond rect.fourth-level {
fill: #E4087D;
}
svg.level-diamond text.fourth-level {
font-size: 14px;
font-weight: 500;
}
footer {
height: 60px;
width: 100%;
display: block;
margin-top: 20px;
}
.semicircle {
position: absolute;
width: 52px;
height: 52px;
}<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css.css" />
<script src="https://kit.fontawesome.com/a8d572acbe.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="app.js" type="text/javascript"></script>
</head>
<body class="dark-mode">
<header></header>
<main>
<div class="container">
<div class="row">
<div class="col-2 p-t-180">
<div class="nav-container">
<div id="main-diamond" style="z-index: 200;">
<div class="controls-container">
<div class="pointer-arrow top" id="pointer-arrow-top"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow right" id="pointer-arrow-right"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow bottom" id="pointer-arrow-bottom"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow left" id="pointer-arrow-left"><i class="fas fa-triangle"></i></div>
<div class="center-icon">
<i class="fad fa-fingerprint"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-4 pl-1 p-t-180">
<div class="node-container" data-first data-state="active" data-node-number="1" data-index="0" style="left:0px; top:0px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-1"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">1</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 1 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="2" data-index="1" style="left:-40px; top:-1px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-2"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">2</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 2 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="3" data-index="2" style="left:-80px; top:-2px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-3"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">3</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 3 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="4" data-index="3" style="left:-120px; top:-3px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-4"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">4</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 4 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="5" data-index="4" style="left:-160px; top:-4px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-5"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">5</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 5 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="6" data-index="5" style="left:-200px; top:-5px">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-6"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">6</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 6 of 6</span>
</div>
</div>
</div>
</div>
</div>
</main>
<footer></footer>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/app.js"></script>
</body>
</html>
发布于 2020-03-29 10:07:35
当您单击buton时,您可以尝试隐藏它们并使它们重新出现。
https://stackoverflow.com/questions/60869548
复制相似问题