javascript - 滚动时根据线性渐变背景设置适当的元素颜色

标签 javascript css algorithm react-native math

我需要一些有关数学/算法问题的帮助。 (你不需要了解react-native来解决这个问题;只需一些数学知识即可)

我有一个具有线性渐变背景的 react native 应用程序 从 rgb(24, 205, 246) 到 rgb(67, 33, 140)。

共有三个不同的文本元素,每个元素位于屏幕上不同的垂直(y 轴)位置。对于每个文本项,我希望其文本颜色与滚动时当前 y 位置的线性渐变背景的颜色相对应。

这就是我想要的样子:/image/WGRSy.jpg

我找到了一个使用background-clip: Text的解决方案,但不幸的是,它仅适用于浏览器,不适用于手机。

经过一番研究,我决定使用scrollview 中的onscroll 方法,该方法将返回手机屏幕顶部的y 位置。当用户向下滑动时,y 位置增加,当用户向上滑动时,y 位置减少。

以下是有关手机屏幕的一些信息:/image/VQFtg.jpg .

我已经做的是对于每个文本项,其颜色将调用函数调用changeColor(文本项A的y位置),该函数将获取文本项的y位置并返回适当的rgb颜色。

changeColor = bname => {
    let topY = this.state.topY;

    let color1 = Math.round(67 - topY / ((24 / 67) * 100));
    let color2 = Math.round(33 + topY / ((33 / 205) * 30));
    let color3 = Math.round(140 + topY / ((140 / 246) * 15));

    return `rgb(${color1},${color2},${color3})`;
};

回想一下,线性渐变背景是从 rgb(24, 205, 246) 到 rgb(67, 33, 140)。我们可以分成三个不同的颜色部分:rgb(color1, color2, color3)。

以color1为例,color1的范围是24到67,手机屏幕的高度是0到677。

我的逻辑是让rgb和height模拟成相同?假设我们有两个变量:topY(向下滑动时增加;向上滑动时减少)和从 24 开始的 rgbVar。

滑动前:

顶部Y:0

rgbVar:24

滑到中间时:

顶部Y:338.5

rgbVar:45.5

滑入末尾时:

顶部Y:667

rgbVar:67

此外,因为文本项位于不同的 Y 位置,所以我需要做一些数学运算并将其添加到计算中?

这是我到目前为止所得到的: https://snack.expo.io/@rex_rau/paranoid-toffee

它可以在某种程度上更改为文本项 A 的适当颜色,但是,文本项 B 和文本项 C 没有不同(不是适合其当前位置的颜色)。

当滑动到中间时,我希望输出是这样的:

  • 文本项 A 的颜色为 rgb(45.5, 119, 193)
  • 文本项 B 的颜色为 rgb(50, 70, 173)
  • 文本项 C 具有 rgb(55, 40, 153)

有人有解决这个问题的想法吗?或者其他方法来实现我想要的?

谢谢

最佳答案

在此应用程序中,文本项的颜色取决于其相对于背景的位置。颜色分量值(红色、绿色、蓝色)从渐变的一端到另一端均呈线性变化。这意味着,如果您要在 x 轴上以数学方式绘制位置,在 y 轴上绘制颜色分量值,您将得到一条具有斜率和 y 截距的线。

正如您所知,线性方程的斜率截距形式为

y = mx + b

其中 m 是直线的斜率,b 是 y 轴截距。

给定线上的两个点 (x1, y1)(x2, y2),可以根据以下公式计算斜率 m方程

m = (y2 - y1)/(x2 - x1)

现在让我们将其应用于手头的问题。对于红色分量,我们可以将这两个点定义为

(x1, y1) = (位置1, 颜色1) = (0, 24)

(x2, y2) = (位置2, 颜色2) = (屏幕高度, 67)

由于每条线的 y 轴截距发生在 x = 0 处,请注意,由于 position1 = 0 我们可以说 y 轴截距 b =颜色1 = 24

所以方程的斜截式为

文本颜色 = 颜色 1 + 文本位置 * (颜色 2 - 颜色 1)/(位置 2 - 位置 1)

每个颜色分量(红、绿、蓝)都使用相同的公式。

在您的 changeColor 函数中,您需要提供一个参数来提供文本项的垂直位置。为此,我将您的参数 bname 重命名为 y。您需要修改三个位置的调用代码,以便它提供数字位置值而不是字符串。

在下面的代码中,我重新排列了上述线性方程中的一些项,但原理没有改变。

changeColor = y => {
    let topY = this.state.topY;

    const topRed = 24
    const topGreen = 205
    const topBlue = 246
    const bottomRed = 67
    const bottomGreen = 33
    const bottomBlue = 140

    let pos = (y - topY) / screenHeight

    let colorRed = topRed + (bottomRed - topRed) * pos
    let colorGreen = topGreen + (bottomGreen - topGreen) * pos
    let colorBlue = topBlue + (bottomBlue - topBlue) * pos

    return `rgb(${colorRed},${colorGreen},${colorBlue})`;
  };

关于javascript - 滚动时根据线性渐变背景设置适当的元素颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57344278/

相关文章:

javascript - 在 React.Component 的 ES6 类实例上调用方法

Javascript:代码在放入函数时不会被执行

algorithm - Pagerank 与 SVD

algorithm - 使用蛮力计算两个不同数组元素之间的最小绝对值差异

python - 模拟抛硬币实验 - RealPython

javascript - Backbone.js View 事件未触发

javascript - d3.js 中每一行的多个列值的总和

javascript - 我尝试将所有黑色代码更改为白色代码

html - 如何将菜单置于顶部栏的中央?

CSS:根据单页导航中的 ID 在部分中定位 DIV