Reactjs 如何模糊滚动上的背景图像?
Reactjs Howto Blur Background image on scroll?
我是 reactjs 的新手,我想了解如何在 Reactjs 样式组件中重现这个 jquery 示例:模糊事件背景图像 "Scroll"
https://jsfiddle.net/BinaryMoon/8jhw2/
$(document).ready(function() {
$(window).scroll(function(e) {
var s = $(window).scrollTop(),
opacityVal = (s / 200);
$('.blurred-image').css('opacity', opacityVal);
});
});
.img-src {
position: absolute;
background:url(http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600) center center;
background-size: cover;
}
如您所见,背景 url 设置为 css prop
我在 reactjs 中尝试过一些东西,但每次滚动时,图像背景都会重新加载。
有人可以帮我吗?
ps : 如果解决方案可以用 styled-components 实现,那就太棒了
ps2:这是我正在尝试实现的效果的另一页
https://codepen.io/zrichard/pen/wEFBd
谢谢
您可以使用 the useEffect hook 将事件侦听器绑定到 window。
import React, { useState, useEffect } from "react";
import styled, { css } from "styled-components";
import { hydrate, render } from "react-dom";
function App() {
const [opacity, setOpacity] = useState(0);
useEffect(() => {
const onScroll = () => setOpacity(window.scrollY / 200);
window.addEventListener("scroll", onScroll);
return function cleanup() {
window.removeEventListener("scroll", onScroll);
};
}, []);
return (
<React.Fragment>
<BlurredImageContainer>
<ImgSrc />
<ImgSrc blurred opacity={opacity} />
</BlurredImageContainer>
<Content>
<Avatar src="https://pbs.twimg.com/profile_images/378800000748837969/bd8e553e5cae83ef488c6b15166bdd55.png" />
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
</Content>
</React.Fragment>
);
}
const BlurredImageContainer = styled.div`
display: block;
padding: 0;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
`;
const ImgSrc = styled.div`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600") center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
${props => props.blurred && css`
opacity: ${props.opacity};
filter: blur(20px) brightness(0.7);
`};
`;
const Content = styled.div`
padding: 150px 50px;
color: #fff;
text-align: center;
`;
const Avatar = styled.div`
height: 120px;
width: 120px;
border-radius: 100%;
border: 5px solid #fff;
margin: 0 auto 50px;
`;
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}
您的示例代码非常好,除了一件很难用所有这些框架正确实现的事情:SCROLLING。
如果你打开一个调试控制台,你会看到这种警告信息(当你上下滚动时,如果你快速滚动显示会"blank")
Over 200 classes were generated for component bg-opacity-v2__ImgSrc.
Consider using the attrs method, together with a style object for frequently changed styles.
Example:
const Component = styled.div.attrs({
style: ({ background }) => ({
background,
}),
})`width: 100%;`
<Component />
我找到了使用组件“.attrs”方法的解决方案。
const ImgSrc = styled.div.attrs(props => ({
style: {
opacity: `${props.opacity}`,
filter: "blur(" + `${props.filter}` + "px) brightness(0.7)",
},
}))`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600")
center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
`
这是您的代码的新版本。我删除了第一个标签,修改了不透明度计算,但这是一个细节。
我真的不明白为什么我必须从 "useEffect" 方法中提取不透明度计算,但它工作得很好。
const onScroll = () => {
setOpacity(scrollOpacity())
setFilter(scrollFilter())
}
这个新版本运行良好。
import React, { useState, useEffect } from "react";
import styled, { css } from "styled-components";
import { hydrate, render } from "react-dom";
function scrollOpacity() {
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
const height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
const scrolled = winScroll / height;
const newOpacity = 1 + scrolled * 2;
return newOpacity;
}
function scrollFilter() {
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
const newFilter = 0 + winScroll / 100;
return newFilter;
}
function App() {
const [opacity, setOpacity] = useState(1);
const [filter, setFilter] = useState(0);
useEffect(() => {
const onScroll = () => {
setOpacity(scrollOpacity());
setFilter(scrollFilter());
};
window.addEventListener("scroll", onScroll);
return function cleanup() {
window.removeEventListener("scroll", onScroll);
};
}, []);
return (
<React.Fragment>
<BlurredImageContainer>
<ImgSrc opacity={opacity} filter={filter} />
</BlurredImageContainer>
<Content>
<Avatar src="https://pbs.twimg.com/profile_images/378800000748837969/bd8e553e5cae83ef488c6b15166bdd55.png" />
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
</Content>
</React.Fragment>
);
}
const BlurredImageContainer = styled.div`
display: block;
padding: 0;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
`;
const ImgSrc = styled.div.attrs(props => ({
style: {
opacity: `${props.opacity}`,
filter: "blur(" + `${props.filter}` + "px) brightness(0.7)"
}
}))`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600")
center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
`;
const Content = styled.div`
padding: 150px 50px;
color: #fff;
text-align: center;
`;
const Avatar = styled.div`
height: 120px;
width: 120px;
border-radius: 100%;
border: 5px solid #fff;
margin: 0 auto 50px;
`;
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}
如果有人有优化或更好的方法来做到这一点,欢迎您。
我是 reactjs 的新手,我想了解如何在 Reactjs 样式组件中重现这个 jquery 示例:模糊事件背景图像 "Scroll" https://jsfiddle.net/BinaryMoon/8jhw2/
$(document).ready(function() {
$(window).scroll(function(e) {
var s = $(window).scrollTop(),
opacityVal = (s / 200);
$('.blurred-image').css('opacity', opacityVal);
});
});
.img-src {
position: absolute;
background:url(http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600) center center;
background-size: cover;
}
如您所见,背景 url 设置为 css prop 我在 reactjs 中尝试过一些东西,但每次滚动时,图像背景都会重新加载。 有人可以帮我吗?
ps : 如果解决方案可以用 styled-components 实现,那就太棒了
ps2:这是我正在尝试实现的效果的另一页 https://codepen.io/zrichard/pen/wEFBd
谢谢
您可以使用 the useEffect hook 将事件侦听器绑定到 window。
import React, { useState, useEffect } from "react";
import styled, { css } from "styled-components";
import { hydrate, render } from "react-dom";
function App() {
const [opacity, setOpacity] = useState(0);
useEffect(() => {
const onScroll = () => setOpacity(window.scrollY / 200);
window.addEventListener("scroll", onScroll);
return function cleanup() {
window.removeEventListener("scroll", onScroll);
};
}, []);
return (
<React.Fragment>
<BlurredImageContainer>
<ImgSrc />
<ImgSrc blurred opacity={opacity} />
</BlurredImageContainer>
<Content>
<Avatar src="https://pbs.twimg.com/profile_images/378800000748837969/bd8e553e5cae83ef488c6b15166bdd55.png" />
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
</Content>
</React.Fragment>
);
}
const BlurredImageContainer = styled.div`
display: block;
padding: 0;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
`;
const ImgSrc = styled.div`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600") center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
${props => props.blurred && css`
opacity: ${props.opacity};
filter: blur(20px) brightness(0.7);
`};
`;
const Content = styled.div`
padding: 150px 50px;
color: #fff;
text-align: center;
`;
const Avatar = styled.div`
height: 120px;
width: 120px;
border-radius: 100%;
border: 5px solid #fff;
margin: 0 auto 50px;
`;
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}
您的示例代码非常好,除了一件很难用所有这些框架正确实现的事情:SCROLLING。
如果你打开一个调试控制台,你会看到这种警告信息(当你上下滚动时,如果你快速滚动显示会"blank")
Over 200 classes were generated for component bg-opacity-v2__ImgSrc. Consider using the attrs method, together with a style object for frequently changed styles.
Example:
const Component = styled.div.attrs({
style: ({ background }) => ({
background,
}),
})`width: 100%;`
<Component />
我找到了使用组件“.attrs”方法的解决方案。
const ImgSrc = styled.div.attrs(props => ({
style: {
opacity: `${props.opacity}`,
filter: "blur(" + `${props.filter}` + "px) brightness(0.7)",
},
}))`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600")
center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
`
这是您的代码的新版本。我删除了第一个标签,修改了不透明度计算,但这是一个细节。 我真的不明白为什么我必须从 "useEffect" 方法中提取不透明度计算,但它工作得很好。
const onScroll = () => {
setOpacity(scrollOpacity())
setFilter(scrollFilter())
}
这个新版本运行良好。
import React, { useState, useEffect } from "react";
import styled, { css } from "styled-components";
import { hydrate, render } from "react-dom";
function scrollOpacity() {
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
const height =
document.documentElement.scrollHeight -
document.documentElement.clientHeight;
const scrolled = winScroll / height;
const newOpacity = 1 + scrolled * 2;
return newOpacity;
}
function scrollFilter() {
const winScroll =
document.body.scrollTop || document.documentElement.scrollTop;
const newFilter = 0 + winScroll / 100;
return newFilter;
}
function App() {
const [opacity, setOpacity] = useState(1);
const [filter, setFilter] = useState(0);
useEffect(() => {
const onScroll = () => {
setOpacity(scrollOpacity());
setFilter(scrollFilter());
};
window.addEventListener("scroll", onScroll);
return function cleanup() {
window.removeEventListener("scroll", onScroll);
};
}, []);
return (
<React.Fragment>
<BlurredImageContainer>
<ImgSrc opacity={opacity} filter={filter} />
</BlurredImageContainer>
<Content>
<Avatar src="https://pbs.twimg.com/profile_images/378800000748837969/bd8e553e5cae83ef488c6b15166bdd55.png" />
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
<p>This is some test content</p>
</Content>
</React.Fragment>
);
}
const BlurredImageContainer = styled.div`
display: block;
padding: 0;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
`;
const ImgSrc = styled.div.attrs(props => ({
style: {
opacity: `${props.opacity}`,
filter: "blur(" + `${props.filter}` + "px) brightness(0.7)"
}
}))`
position: absolute;
background: url("http://bromleydemo.files.wordpress.com/2013/10/blossom.jpg?w=600")
center center;
background-size: cover;
top: -10%;
bottom: 10%;
left: -10%;
right: 10%;
width: 120%;
height: 120%;
`;
const Content = styled.div`
padding: 150px 50px;
color: #fff;
text-align: center;
`;
const Avatar = styled.div`
height: 120px;
width: 120px;
border-radius: 100%;
border: 5px solid #fff;
margin: 0 auto 50px;
`;
const rootElement = document.getElementById("root");
if (rootElement.hasChildNodes()) {
hydrate(<App />, rootElement);
} else {
render(<App />, rootElement);
}
如果有人有优化或更好的方法来做到这一点,欢迎您。