我需要一些有关数学/算法问题的帮助。 (你不需要了解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/