【问题标题】:Changing background linear-grading degree on scroll更改滚动时的背景线性渐变度
【发布时间】:2019-05-14 15:47:49
【问题描述】:

在我的 web 应用程序中,我有这个由 2 个线性渐变组成的背景 我想根据滚动来改变渐变的“倾斜度”

我真的不知道如何做到这一点......

这是当前状态:https://prnt.sc/no3las (所以我想在滚动时使蓝色背景变薄:-))

这是我网站背景的css

html {
  font-family: 'Roboto Mono', monospace;
  background: linear-gradient(70deg, #5870cb 20%, rgba(0, 0, 0, 0) 1%), 
              linear-gradient(20deg, white 85%, #5870cb 2%);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
  height: 100vh;
}

【问题讨论】:

  • 请分享您编写此代码的最佳尝试。没有它,或者至少没有大量的文档工作,根据定义,您不是程序员,而是客户。这使您的问题在本网站上离题。请阅读How to Ask。特别是,您希望使用 JavaScript 在绑定到窗口的scroll 的函数内,根据scrollTop 的值逐渐更改元素的background 值。
  • 我实际上不知道如何开始。我对scrollmagic(scrollmagic.io)和laxxx(github.com/alexfoxy/laxxx)等滚动库进行了一些研究,但它们似乎都无法修改背景属性。如果有人能给我资源,那将是一个很大的帮助所以我可以自己弄清楚。我不希望你给我发我可以复制的代码...
  • 我正在尝试在滚动上修改这些值.... 背景:linear-gradient(70deg, #5870cb 20%, rgba(0, 0, 0, 0 ) 1%), 线性渐变(20deg, 白色 85%, #5870cb 2%);``
  • 您希望它以哪种方式制作动画? “修改这些值”的每一种方法都是不同的,有些可能非常困难。

标签: javascript html css angularjs


【解决方案1】:

要旋转渐变,您需要了解(并解构)linear-gradient(实际上是background-image)。可以在 MDN 上找到一个很好的纲要,官方规范在 CSSWG (W3C)。

首先要知道的是你不能移动它的中心。由于是元素的背景,所以渐变的中心永远是元素的中心。
注意:如果您的设计需要不同的旋转中心,您始终可以使用超过 1 个元素并相应地调整它们的大小。

现在,假设您要将第一个渐变从70deg 旋转到110deg,将第二个渐变从20deg 旋转到155deg

快速搜索scroll event 将(希望)让您找到MDN's page,其中有一个示例。

将它与上面结合起来,你会得到一些类似的东西(我将旋转 backgroundImage 的逻辑放在示例的 doSomething 函数中)。

我还指定了我从哪里获取每一点,以展示如何逐步记录您的问题。这里的重点是:你可以自己做的每一件事,去做,只留下你不知道的部分。

let last_known_scroll_position = 0;
let ticking = false;

// helpers
const body = document.querySelector('body');
const html = document.querySelector('html');

function doSomething(scroll_pos) {

 // from https://stackoverflow.com/a/1147768/1891677 :
 const bodyHeight = Math.max( body.scrollHeight, 
                              body.offsetHeight, 
                              html.clientHeight, 
                              html.scrollHeight, 
                              html.offsetHeight);
 
 // from https://stackoverflow.com/a/8876069/1891677 :
 const viewportHeight = Math.max(document.documentElement.clientHeight,
                                 window.innerHeight || 0);
 
 // set scrollPercentage, if we have available scroll (0 otherwise):
 const availableScroll = bodyHeight - viewportHeight;
 const percentage = availableScroll > 0 ? scroll_pos * 100/availableScroll : 0;
  
 // this is what the question is about:
 const fromPercent = (from,to,current) => ((to - from) * current/100) + from;
 body.style.backgroundImage = `
 linear-gradient(${fromPercent(70, 110, percentage)}deg, #5870cb 20%, rgba(0,0,0,0) 0),
 linear-gradient(${fromPercent(20, 155, percentage)}deg, white 85%, #5870cb 2%)
 `;
}

// rest of example, from MDN:
window.addEventListener('scroll', function(e) {
  last_known_scroll_position = window.scrollY;

  if (!ticking) {
    window.requestAnimationFrame(function() {
      doSomething(last_known_scroll_position);
      ticking = false;
    });

    ticking = true;
  }
});
body {
  font-family: 'Roboto Mono', monospace;
  background-image: linear-gradient(70deg, #5870cb 20%, rgba(0,0,0,0) 1%), 
                    linear-gradient(20deg, white 85%, #5870cb 2%);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
  height: 300vh;
}

【讨论】:

  • 谢谢!它工作得很好,我不得不改变一件事。我的背景设置在 html 标签而不是 body 标签上。所以我有这个:``` const fromPercent = (from,to,current) => ((to - from) * current/100) + from; html.style.backgroundImage = `linear-gradient(${fromPercent(70, 110, percent)}deg, #5870cb 20%, rgba(0,0,0,0) 0), linear-gradient(${fromPercent( 20, 155, 百分比)}deg, white 85%, #5870cb 2%) `; }```谢谢! (这是结果:gyazo.com/fecc130facf6b35771302866c4047aad
  • 我会听取您对 SO 的建议以解决未来的问题,也谢谢您
【解决方案2】:

基本上,您需要的是当前滚动位置(通过.scrollTop)以及最大滚动距离(<SCROLLING_ELEMENT>.scrollHeight - window.innerHeight)。如果你有这些信息,你可以用一点 JS 轻松计算渐变的旋转/角度:

// HTML :: Element
const HTML = document.documentElement;

// getCurrentScroll :: () -> Number
const getCurrentScroll = () => HTML.scrollTop;

// getMaxScroll :: () -> Number
const getMaxScroll = () => HTML.scrollHeight - window.innerHeight;

// calcRotation :: (Number, Number) -> Number
const calcRotation = (pos, max) => pos / max * 360;

// getBG :: Number -> String
const getBG = r => `linear-gradient(${r + 70}deg, #5870cb 20%, rgba(0,0,0,0) 1%), linear-gradient(${r + 20}deg, white 85%, #5870cb 2%)`;



document.addEventListener('scroll', () => {
  const rot = calcRotation(getCurrentScroll(), getMaxScroll());
  HTML.style.backgroundImage = getBG(rot);
});
html {
  font-family: 'Roboto Mono', monospace;
  background: linear-gradient(70deg, #5870cb 20%, rgba(0, 0, 0, 0) 1%), 
  linear-gradient(20deg, white 85%, #5870cb 2%);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: fixed;
  height: 100vh;
  overflow: auto; /* no scrolling without this line */
}

body { height: 200vh; } /* just to create a scroll bar */

【讨论】:

    猜你喜欢
    • 2020-11-18
    • 2018-10-14
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多