javascript - svg 在不同部分的流体颜色变化

标签 javascript css svg

我正在尝试根据 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/

相关文章:

javascript - setTimeout 不添加延迟

javascript删除动态生成tr td中的最后一个子项

Jquery Ui Sortable 在 IE8 中显示损坏的图像

javascript - 响应式网页设计适用于桌面设备,但不适用于移动设备,它不会加载 CSS 和 JavaScript

php - 真正的随机数

HTML 电子邮件内容的 css 未在 gmail 中应用

javascript - JavaScript 中的精确动态 SVG 用于行为实验

javascript - 悬停时的 SVG 圆形动画描边

css - 使用 CSS 定位 SVG

javascript - 使用文件中的内容加载文本区域