我正在尝试根据 SVG 的当前部分背景更改其颜色...它与形状一起工作,但是一旦我将其更改为路径,它就会跳跃颜色而不是流体变化...为什么那?
这就是我想要实现的目标(颜色的流畅过渡)
var sections = document.querySelectorAll('section');
var logo = document.querySelector('#logo');
var nextColor = document.querySelector('#nextColor');
var currentColor = document.querySelector('#currentColor');
var initialHeight = logo.clientHeight;
var lastScrollPosition = 0;
// Set current section color
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
if (top <= logo.offsetTop && (top + section.clientHeight) >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
});
window.addEventListener('scroll', function () {
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
var offset = top - logo.offsetTop;
// If the top edge of the section is behind the logo
if (top <= logo.offsetTop) {
// Make sure the section color has its initial height
currentColor.setAttribute('height', initialHeight);
// If the logo is still inside the section, fill it with the section color
var bottom = top + section.clientHeight;
if (bottom >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
return;
}
// If logo collides with the lower section
if (offset <= logo.clientHeight) {
nextColor.setAttribute('fill', section.dataset.color);
currentColor.setAttribute('height', offset);
}
});
});
#logo {
position: fixed;
position: fixed;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
section {
height: 100vh
}
#dark {
background-color: #2a2a2a;
}
<div id="logo">
<svg height="100" width="100">
<rect id="nextColor" width="100" height="100"/>
<rect id="currentColor" y="0" width="100" height="100"/>
</svg>
</div>
<div class="sections">
<section data-color="#000000" id="light"></section>
<section data-color="#ffffff" id="dark"></section>
<section data-color="#cccccc" id="light2"></section>
</div>
这是我得到的,但它不像上面的工作示例那样顺利过渡:
var sections = document.querySelectorAll('section');
var logo = document.querySelector('#logo');
var nextColor = document.querySelector('#nextColor');
var currentColor = document.querySelector('#currentColor');
var initialHeight = logo.clientHeight;
var lastScrollPosition = 0;
// Set current section color
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
if (top <= logo.offsetTop && (top + section.clientHeight) >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
});
window.addEventListener('scroll', function () {
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
var offset = top - logo.offsetTop;
// If the top edge of the section is behind the logo
if (top <= logo.offsetTop) {
// Make sure the section color has its initial height
currentColor.setAttribute('height', initialHeight);
// If the logo is still inside the section, fill it with the section color
var bottom = top + section.clientHeight;
if (bottom >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
return;
}
// If logo collides with the lower section
if (offset <= logo.clientHeight) {
nextColor.setAttribute('fill', section.dataset.color);
currentColor.setAttribute('height', offset);
}
});
});
#logo {
position: fixed;
position: fixed;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
section {
height: 100vh
}
#blue {
background-color: #b4da55;
}
<div id="logo">
<svg height="48" xmlns="http://www.w3.org/2000/svg">
<path height="48" id="nextColor" d="M5.8 0v36.3h10.7V48l25.6-11.7V0H5.8zm10.5"/>
<path height="48" id="currentColor" y="0" d="M5.8 0v36.3h10.7V48l25.6-11.7V0H5.8zm10.5"/>
</svg>
</div>
<div class="sections">
<section data-color="#b4da55" id="white"></section>
<section data-color="#ffffff" id="blue"></section>
<section data-color="#b4da55" id="white"></section>
</div>
最佳答案
您的代码没有按照我认为您认为的方式使用 SVG 矩形形状。为了演示这一点,我将 rect
更改为 ellipse
,然后根据需要更改属性,即 y
更改为 cy
,宽度
到rx
,高度
到ry
。结果表明,该形状首先仅显示整个形状的一部分(右下四分之一?),其次,当截面边框覆盖该形状时,实际上会挤压该形状。您在原始示例中看不到这些内容,因为矩形的四分之一仍然是矩形,并且压扁的矩形也仍然是矩形。因此,您认为在原始示例中起作用的内容实际上不起作用。所以问题不在于使用路径,而是你的原始代码。
如果您只想使用矩形,我想您可以按原样使用原始代码,因为它确实产生所需的视觉效果。但是,如果您仅使用矩形作为概念验证,并且真正的最终目标是使用路径,那么您需要采用不同的方法。您可能会考虑使用 clipPath
/clip-path
将路径“切割”成多个部分,因为节边框经过它,但这需要对路径进行一些重大的修改你的代码。
var sections = document.querySelectorAll('section');
var logo = document.querySelector('#logo');
var nextColor = document.querySelector('#nextColor');
var currentColor = document.querySelector('#currentColor');
var initialHeight = logo.clientHeight;
var lastScrollPosition = 0;
// Set current section color
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
if (top <= logo.offsetTop && (top + section.clientHeight) >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
});
window.addEventListener('scroll', function () {
sections.forEach(function (section) {
var top = section.offsetTop - window.pageYOffset;
var offset = top - logo.offsetTop;
// If the top edge of the section is behind the logo
if (top <= logo.offsetTop) {
// Make sure the section color has its initial height
currentColor.setAttribute('ry', initialHeight);
// If the logo is still inside the section, fill it with the section color
var bottom = top + section.clientHeight;
if (bottom >= logo.offsetTop) {
currentColor.setAttribute('fill', section.dataset.color);
}
return;
}
// If logo collides with the lower section
if (offset <= logo.clientHeight) {
nextColor.setAttribute('fill', section.dataset.color);
currentColor.setAttribute('ry', offset);
}
});
});
#logo {
position: fixed;
position: fixed;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
}
section {
height: 100vh
}
#dark {
background-color: #2a2a2a;
}
<div id="logo">
<svg height="100" width="100">
<ellipse id="nextColor" rx="100" ry="100"/>
<ellipse id="currentColor" cy="0" rx="100" ry="100"/>
</svg>
</div>
<div class="sections">
<section data-color="#000000" id="light"></section>
<section data-color="#ffffff" id="dark"></section>
<section data-color="#cccccc" id="light2"></section>
</div>
关于javascript - svg 在不同部分的流体颜色变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44563146/