如何触发包含三个重叠 div 元素的 :hover 过渡(维恩图)
How can I trigger a :hover transition that includes three overlapping div elements (Venn diagram)
我的问题是我有这个由三个 div 元素组成的维恩图,我想用 :hover
缩放它们,这样当我将鼠标悬停在一个交叉点上时,所有在交叉点缩放到我定义的值。目前我只得到一个圈来缩放。
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.circle-blue {
position: absolute;
left: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(187, 231, 254, 0.6);
border-radius: 50%;
}
.circle-purple {
position: absolute;
right: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(211, 181, 229, 0.6);
border-radius: 50%;
}
.circle-pink {
position: absolute;
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(255, 212, 219, 0.6);
border-radius: 50%;
}
.second-section-circle {
transition: all, 1s;
}
.second-section-circle:hover {
transform: scale(1.1);
}
<div class="circles-container">
<div class="circle-blue second-section-circle"></div>
<div class="circle-purple second-section-circle"></div>
<div class="circle-pink second-section-circle"></div>
</div>
你可以做到这一点,但你需要一点 JavaScript。别担心,没有什么太复杂的。你可以做的是使用 element.getBoundingClientRect()
方法获取每个圆的尺寸,就像这样...
let blue = document.querySelector(".circle-blue").getBoundingClientRect();
let purple = document.querySelector(".circle-purple").getBoundingClientRect();
let pink = document.querySelector(".circle-pink").getBoundingClientRect();
然后每次用户移动鼠标时,您可以测试鼠标是否在给定元素上,如果是,您可以缩放它,而不管哪个元素与另一个元素重叠,因此导致任何圆圈缩放,包括交叉点中包含的圆...
let blue = document.querySelector(".circle-blue").getBoundingClientRect();
let purple = document.querySelector(".circle-purple").getBoundingClientRect();
let pink = document.querySelector(".circle-pink").getBoundingClientRect();
window.addEventListener("mousemove", (e) => {
let x = e.pageX,y = e.pageY;
//test blue...
if (x > blue.left && x < blue.right && y > blue.top && y < blue.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-blue").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-blue").style.transform = "scale(1)";
}
//test purple...
if (x > purple.left && x < purple.right && y > purple.top && y < purple.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-purple").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-purple").style.transform = "scale(1)";
}
//test pink...
if (x > pink.left && x < pink.right && y > pink.top && y < pink.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-pink").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-pink").style.transform = "scale(1)";
}
});
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.circle-blue {
position: absolute;
left: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(187, 231, 254, 0.6);
border-radius: 50%;
}
.circle-purple {
position: absolute;
right: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(211, 181, 229, 0.6);
border-radius: 50%;
}
.circle-pink {
position: absolute;
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(255, 212, 219, 0.6);
border-radius: 50%;
}
.second-section-circle {
transition: all, 1s;
}
<div class="circles-container">
<div class="circle-blue second-section-circle"></div>
<div class="circle-purple second-section-circle"></div>
<div class="circle-pink second-section-circle"></div>
</div>
我完成了 ,这样圆圈就会对越过它们的边界做出反应,而不是它们周围描述的正方形的边界。
并且还添加了辅助函数和循环,以免手动列出图中的所有圆圈。现在脚本代码不依赖于图中的圆圈数。
https://codepen.io/glebkema/pen/OJjNwzd
let circlesElements = document.getElementsByClassName("second-section-circle");
let circlesInfo = [];
for (let elem of circlesElements) {
circlesInfo.push(getCircleInfo(elem));
}
// console.log(circlesInfo);
window.addEventListener("mousemove", (e) => {
for (let info of circlesInfo) {
let deltaX = e.pageX - info.centerX;
let deltaY = e.pageY - info.centerY;
if (deltaX * deltaX + deltaY * deltaY <= info.radius2) {
// if mouse is over element, scale it...
info.elem.style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
info.elem.style.transform = "scale(1)";
}
}
});
function getCircleInfo(elem) {
let rect = elem.getBoundingClientRect();
let radius = (rect.right - rect.left) / 2;
return {
elem: elem,
centerX: (rect.right + rect.left) / 2,
centerY: (rect.bottom + rect.top) / 2,
radius2: radius * radius
};
}
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.second-section-circle {
position: absolute;
width: 28.4375rem;
height: 28.4375rem;
border-radius: 50%;
transition: all, 1s;
}
.circle-blue {
left: 0rem;
top: 0rem;
background-color: rgba(187, 231, 254, 0.6);
}
.circle-pink {
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
background-color: rgba(255, 212, 219, 0.6);
}
.circle-purple {
right: 0rem;
top: 0rem;
background-color: rgba(211, 181, 229, 0.6);
}
<div class="circles-container">
<div class="second-section-circle circle-blue"></div>
<div class="second-section-circle circle-purple"></div>
<div class="second-section-circle circle-pink"></div>
</div>
一个 CSS 唯一的解决方案,它需要更多元素和一个 CSS 变量来控制大小:
.circles-container {
--s:150px; /* adjust this to control the size*/
width: var(--s);
height: var(--s);
margin:calc(var(--s)/3) auto;
display:grid;
}
.circles-container > * {
grid-area: 1/1;
transition: all 1s;
border-radius:50%;
position:relative;
}
.circle-blue {
background: rgba(187, 231, 254, 0.6);
top:calc(var(--s)/3);
}
.circle-purple {
background: rgba(211, 181, 229, 0.6);
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circle-pink {
background: rgba(255, 212, 219, 0.6);
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circles-container > *:nth-child(1) {
top:calc(var(--s)/3);
clip-path:circle(calc(var(--s)/2) at 21% 0%);
}
.circles-container > *:nth-child(2) {
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 108% 50%);
}
.circles-container > *:nth-child(3) {
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 21% 100%);
}
.circles-container > *:nth-child(4) {
clip-path: polygon(29% 38%, 50% 34%, 71% 38%, 64% 60%, 50% 74%, 36% 60%);
}
.circles-container > *:nth-child(-n + 4) {
z-index:1;
}
.circles-container > *:nth-child(1):hover ~ .circle-pink,
.circles-container > *:nth-child(1):hover ~ .circle-blue,
.circles-container > *:nth-child(2):hover ~ .circle-pink,
.circles-container > *:nth-child(2):hover ~ .circle-purple,
.circles-container > *:nth-child(3):hover ~ .circle-blue,
.circles-container > *:nth-child(3):hover ~ .circle-purple,
.circles-container > *:nth-child(4):hover ~ *,
.circles-container > *:nth-child(n + 5):hover {
transform: scale(1.15);
}
<div class="circles-container">
<div></div>
<div></div>
<div></div>
<div></div>
<div class="circle-blue"></div>
<div class="circle-purple"></div>
<div class="circle-pink"></div>
</div>
为额外的 div 添加背景颜色以理解拼图:
.circles-container {
--s:150px; /* adjust this to control the size*/
width: var(--s);
height: var(--s);
margin:calc(var(--s)/3) auto;
display:grid;
}
.circles-container > * {
grid-area: 1/1;
transition: all 1s;
border-radius:50%;
position:relative;
}
.circle-blue {
background: rgba(187, 231, 254, 0.6);
top:calc(var(--s)/3);
}
.circle-purple {
background: rgba(211, 181, 229, 0.6);
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circle-pink {
background: rgba(255, 212, 219, 0.6);
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circles-container > *:nth-child(1) {
top:calc(var(--s)/3);
clip-path:circle(calc(var(--s)/2) at 21% 0%);
}
.circles-container > *:nth-child(2) {
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 108% 50%);
}
.circles-container > *:nth-child(3) {
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 21% 100%);
}
.circles-container > *:nth-child(4) {
clip-path: polygon(29% 38%, 50% 34%, 71% 38%, 64% 60%, 50% 74%, 36% 60%);
}
.circles-container > *:nth-child(-n + 4) {
z-index:1;
}
.circles-container > *:nth-child(1):hover ~ .circle-pink,
.circles-container > *:nth-child(1):hover ~ .circle-blue,
.circles-container > *:nth-child(2):hover ~ .circle-pink,
.circles-container > *:nth-child(2):hover ~ .circle-purple,
.circles-container > *:nth-child(3):hover ~ .circle-blue,
.circles-container > *:nth-child(3):hover ~ .circle-purple,
.circles-container > *:nth-child(4):hover ~ *,
.circles-container > *:nth-child(n + 5):hover {
transform: scale(1.15);
}
<div class="circles-container">
<div style="background:red;"></div>
<div style="background:green;"></div>
<div style="background:purple;"></div>
<div style="background:black;"></div>
<div class="circle-blue"></div>
<div class="circle-purple"></div>
<div class="circle-pink"></div>
</div>
我的问题是我有这个由三个 div 元素组成的维恩图,我想用 :hover
缩放它们,这样当我将鼠标悬停在一个交叉点上时,所有在交叉点缩放到我定义的值。目前我只得到一个圈来缩放。
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.circle-blue {
position: absolute;
left: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(187, 231, 254, 0.6);
border-radius: 50%;
}
.circle-purple {
position: absolute;
right: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(211, 181, 229, 0.6);
border-radius: 50%;
}
.circle-pink {
position: absolute;
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(255, 212, 219, 0.6);
border-radius: 50%;
}
.second-section-circle {
transition: all, 1s;
}
.second-section-circle:hover {
transform: scale(1.1);
}
<div class="circles-container">
<div class="circle-blue second-section-circle"></div>
<div class="circle-purple second-section-circle"></div>
<div class="circle-pink second-section-circle"></div>
</div>
你可以做到这一点,但你需要一点 JavaScript。别担心,没有什么太复杂的。你可以做的是使用 element.getBoundingClientRect()
方法获取每个圆的尺寸,就像这样...
let blue = document.querySelector(".circle-blue").getBoundingClientRect();
let purple = document.querySelector(".circle-purple").getBoundingClientRect();
let pink = document.querySelector(".circle-pink").getBoundingClientRect();
然后每次用户移动鼠标时,您可以测试鼠标是否在给定元素上,如果是,您可以缩放它,而不管哪个元素与另一个元素重叠,因此导致任何圆圈缩放,包括交叉点中包含的圆...
let blue = document.querySelector(".circle-blue").getBoundingClientRect();
let purple = document.querySelector(".circle-purple").getBoundingClientRect();
let pink = document.querySelector(".circle-pink").getBoundingClientRect();
window.addEventListener("mousemove", (e) => {
let x = e.pageX,y = e.pageY;
//test blue...
if (x > blue.left && x < blue.right && y > blue.top && y < blue.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-blue").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-blue").style.transform = "scale(1)";
}
//test purple...
if (x > purple.left && x < purple.right && y > purple.top && y < purple.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-purple").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-purple").style.transform = "scale(1)";
}
//test pink...
if (x > pink.left && x < pink.right && y > pink.top && y < pink.bottom) {
// if mouse is over element, scale it...
document.querySelector(".circle-pink").style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
document.querySelector(".circle-pink").style.transform = "scale(1)";
}
});
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.circle-blue {
position: absolute;
left: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(187, 231, 254, 0.6);
border-radius: 50%;
}
.circle-purple {
position: absolute;
right: 0rem;
top: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(211, 181, 229, 0.6);
border-radius: 50%;
}
.circle-pink {
position: absolute;
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
width: 28.4375rem;
height: 28.4375rem;
background-color: rgba(255, 212, 219, 0.6);
border-radius: 50%;
}
.second-section-circle {
transition: all, 1s;
}
<div class="circles-container">
<div class="circle-blue second-section-circle"></div>
<div class="circle-purple second-section-circle"></div>
<div class="circle-pink second-section-circle"></div>
</div>
我完成了
并且还添加了辅助函数和循环,以免手动列出图中的所有圆圈。现在脚本代码不依赖于图中的圆圈数。
https://codepen.io/glebkema/pen/OJjNwzd
let circlesElements = document.getElementsByClassName("second-section-circle");
let circlesInfo = [];
for (let elem of circlesElements) {
circlesInfo.push(getCircleInfo(elem));
}
// console.log(circlesInfo);
window.addEventListener("mousemove", (e) => {
for (let info of circlesInfo) {
let deltaX = e.pageX - info.centerX;
let deltaY = e.pageY - info.centerY;
if (deltaX * deltaX + deltaY * deltaY <= info.radius2) {
// if mouse is over element, scale it...
info.elem.style.transform = "scale(1.2)";
} else {
// otherwise, dont scale it...
info.elem.style.transform = "scale(1)";
}
}
});
function getCircleInfo(elem) {
let rect = elem.getBoundingClientRect();
let radius = (rect.right - rect.left) / 2;
return {
elem: elem,
centerX: (rect.right + rect.left) / 2,
centerY: (rect.bottom + rect.top) / 2,
radius2: radius * radius
};
}
.circles-container {
position: relative;
width: 45.625rem;
height: 45.625rem;
}
.second-section-circle {
position: absolute;
width: 28.4375rem;
height: 28.4375rem;
border-radius: 50%;
transition: all, 1s;
}
.circle-blue {
left: 0rem;
top: 0rem;
background-color: rgba(187, 231, 254, 0.6);
}
.circle-pink {
right: 8.59375rem;
left: 8.59375rem;
bottom: 0rem;
background-color: rgba(255, 212, 219, 0.6);
}
.circle-purple {
right: 0rem;
top: 0rem;
background-color: rgba(211, 181, 229, 0.6);
}
<div class="circles-container">
<div class="second-section-circle circle-blue"></div>
<div class="second-section-circle circle-purple"></div>
<div class="second-section-circle circle-pink"></div>
</div>
一个 CSS 唯一的解决方案,它需要更多元素和一个 CSS 变量来控制大小:
.circles-container {
--s:150px; /* adjust this to control the size*/
width: var(--s);
height: var(--s);
margin:calc(var(--s)/3) auto;
display:grid;
}
.circles-container > * {
grid-area: 1/1;
transition: all 1s;
border-radius:50%;
position:relative;
}
.circle-blue {
background: rgba(187, 231, 254, 0.6);
top:calc(var(--s)/3);
}
.circle-purple {
background: rgba(211, 181, 229, 0.6);
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circle-pink {
background: rgba(255, 212, 219, 0.6);
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circles-container > *:nth-child(1) {
top:calc(var(--s)/3);
clip-path:circle(calc(var(--s)/2) at 21% 0%);
}
.circles-container > *:nth-child(2) {
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 108% 50%);
}
.circles-container > *:nth-child(3) {
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 21% 100%);
}
.circles-container > *:nth-child(4) {
clip-path: polygon(29% 38%, 50% 34%, 71% 38%, 64% 60%, 50% 74%, 36% 60%);
}
.circles-container > *:nth-child(-n + 4) {
z-index:1;
}
.circles-container > *:nth-child(1):hover ~ .circle-pink,
.circles-container > *:nth-child(1):hover ~ .circle-blue,
.circles-container > *:nth-child(2):hover ~ .circle-pink,
.circles-container > *:nth-child(2):hover ~ .circle-purple,
.circles-container > *:nth-child(3):hover ~ .circle-blue,
.circles-container > *:nth-child(3):hover ~ .circle-purple,
.circles-container > *:nth-child(4):hover ~ *,
.circles-container > *:nth-child(n + 5):hover {
transform: scale(1.15);
}
<div class="circles-container">
<div></div>
<div></div>
<div></div>
<div></div>
<div class="circle-blue"></div>
<div class="circle-purple"></div>
<div class="circle-pink"></div>
</div>
为额外的 div 添加背景颜色以理解拼图:
.circles-container {
--s:150px; /* adjust this to control the size*/
width: var(--s);
height: var(--s);
margin:calc(var(--s)/3) auto;
display:grid;
}
.circles-container > * {
grid-area: 1/1;
transition: all 1s;
border-radius:50%;
position:relative;
}
.circle-blue {
background: rgba(187, 231, 254, 0.6);
top:calc(var(--s)/3);
}
.circle-purple {
background: rgba(211, 181, 229, 0.6);
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circle-pink {
background: rgba(255, 212, 219, 0.6);
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
}
.circles-container > *:nth-child(1) {
top:calc(var(--s)/3);
clip-path:circle(calc(var(--s)/2) at 21% 0%);
}
.circles-container > *:nth-child(2) {
right:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 108% 50%);
}
.circles-container > *:nth-child(3) {
left:calc(0.866*calc(var(--s)/3));
top: calc(-0.5 *calc(var(--s)/3));
clip-path:circle(calc(var(--s)/2) at 21% 100%);
}
.circles-container > *:nth-child(4) {
clip-path: polygon(29% 38%, 50% 34%, 71% 38%, 64% 60%, 50% 74%, 36% 60%);
}
.circles-container > *:nth-child(-n + 4) {
z-index:1;
}
.circles-container > *:nth-child(1):hover ~ .circle-pink,
.circles-container > *:nth-child(1):hover ~ .circle-blue,
.circles-container > *:nth-child(2):hover ~ .circle-pink,
.circles-container > *:nth-child(2):hover ~ .circle-purple,
.circles-container > *:nth-child(3):hover ~ .circle-blue,
.circles-container > *:nth-child(3):hover ~ .circle-purple,
.circles-container > *:nth-child(4):hover ~ *,
.circles-container > *:nth-child(n + 5):hover {
transform: scale(1.15);
}
<div class="circles-container">
<div style="background:red;"></div>
<div style="background:green;"></div>
<div style="background:purple;"></div>
<div style="background:black;"></div>
<div class="circle-blue"></div>
<div class="circle-purple"></div>
<div class="circle-pink"></div>
</div>