在 React 中重新加载实时图像而不闪烁
Reload Live Image without Flickering in React
我想在 React 中无限期地以静态 URL 重新加载图像。通过一些搜索,我得出了以下不太理想的解决方案。它有效,但我想消除图像加载的闪烁。我意识到问题是组件被重新渲染,然后图像加载。我见过几个示例,其中一个使用两个图像作为占位符,另一个使用 onLoad
和 setState
隐藏加载,但它们都假设图像数量有限。我怎样才能使它显示 CardMedia
中的最后一张图像,直到加载新图像,然后每五秒更换一次而不闪烁?
import React from 'react';
import ReactDOM from 'react-dom';
import { Card, CardMedia, CardTitle } from 'react-toolbox/lib/card';
const LIVE_IMAGE = 'https://cdn-images-1.medium.com/max/1600/1*oi8WLwC2u0EEI1j9uKmwWg.png';
class LiveImageCard extends React.Component {
constructor(props) {
super(props);
this.state = {
liveImage: null
};
}
componentDidMount() {
this.interval = setInterval(
() => this.setState({
liveImage: `${LIVE_IMAGE}?${new Date().getTime()}`,
}),
5000
);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<Card style={{width: '350px'}}>
<CardTitle title="Live Image" />
<CardMedia
aspectRatio="wide"
image={this.state.liveImage}
/>
</Card>
);
}
}
ReactDOM.render(
<LiveImageCard />,
document.getElementById('root'),
);
不确定这是否是最佳解决方案,但我最终得到了这个并且它的工作原理使您看不到闪烁。
import React from 'react';
import ReactDOM from 'react-dom';
import { Card, CardMedia, CardTitle } from 'react-toolbox/lib/card';
const LIVE_IMAGE = 'https://cdn-images-1.medium.com/max/1600/1*oi8WLwC2u0EEI1j9uKmwWg.png';
class LiveImageCard extends React.Component {
constructor(props) {
super(props);
this.loadImage = () => {
const component = this;
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width =this.width;
canvas.height =this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
component.setState({liveImage: dataURL});
};
img.src = `${LIVE_IMAGE}?${new Date().getTime()}`;
this.setState({ loadingImage: img });
}
this.state = {
loadingImage: null,
liveImage: null
};
}
componentDidMount() {
this.loadImage();
this.interval = setInterval(this.loadImage, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<Card style={{width: '350px'}}>
<CardTitle title="Live Image" />
<CardMedia
aspectRatio="wide"
image={this.state.liveImage}
/>
</Card>
);
}
}
ReactDOM.render(
<LiveImageCard />,
document.getElementById('root'),
);
或者作为没有 React-Toolbox 的独立组件
class LiveImage extends React.Component {
constructor(props) {
super(props);
this.loadImage = () => {
const component = this;
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width =this.width;
canvas.height =this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
component.setState({liveImage: dataURL});
};
img.src = `${this.props.image}?${new Date().getTime()}`;
this.setState({ loadingImage: img });
}
this.state = {
loadingImage: null,
liveImage: null
};
}
componentDidMount() {
this.loadImage();
this.interval = setInterval(this.loadImage, this.props.interval);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<img src={this.state.liveImage} {...this.props} />
);
}
}
对我来说,删除 <Image>
道具,resizeMode={"contain"}
解决了 Android 上的闪烁问题。
我想在 React 中无限期地以静态 URL 重新加载图像。通过一些搜索,我得出了以下不太理想的解决方案。它有效,但我想消除图像加载的闪烁。我意识到问题是组件被重新渲染,然后图像加载。我见过几个示例,其中一个使用两个图像作为占位符,另一个使用 onLoad
和 setState
隐藏加载,但它们都假设图像数量有限。我怎样才能使它显示 CardMedia
中的最后一张图像,直到加载新图像,然后每五秒更换一次而不闪烁?
import React from 'react';
import ReactDOM from 'react-dom';
import { Card, CardMedia, CardTitle } from 'react-toolbox/lib/card';
const LIVE_IMAGE = 'https://cdn-images-1.medium.com/max/1600/1*oi8WLwC2u0EEI1j9uKmwWg.png';
class LiveImageCard extends React.Component {
constructor(props) {
super(props);
this.state = {
liveImage: null
};
}
componentDidMount() {
this.interval = setInterval(
() => this.setState({
liveImage: `${LIVE_IMAGE}?${new Date().getTime()}`,
}),
5000
);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<Card style={{width: '350px'}}>
<CardTitle title="Live Image" />
<CardMedia
aspectRatio="wide"
image={this.state.liveImage}
/>
</Card>
);
}
}
ReactDOM.render(
<LiveImageCard />,
document.getElementById('root'),
);
不确定这是否是最佳解决方案,但我最终得到了这个并且它的工作原理使您看不到闪烁。
import React from 'react';
import ReactDOM from 'react-dom';
import { Card, CardMedia, CardTitle } from 'react-toolbox/lib/card';
const LIVE_IMAGE = 'https://cdn-images-1.medium.com/max/1600/1*oi8WLwC2u0EEI1j9uKmwWg.png';
class LiveImageCard extends React.Component {
constructor(props) {
super(props);
this.loadImage = () => {
const component = this;
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width =this.width;
canvas.height =this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
component.setState({liveImage: dataURL});
};
img.src = `${LIVE_IMAGE}?${new Date().getTime()}`;
this.setState({ loadingImage: img });
}
this.state = {
loadingImage: null,
liveImage: null
};
}
componentDidMount() {
this.loadImage();
this.interval = setInterval(this.loadImage, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<Card style={{width: '350px'}}>
<CardTitle title="Live Image" />
<CardMedia
aspectRatio="wide"
image={this.state.liveImage}
/>
</Card>
);
}
}
ReactDOM.render(
<LiveImageCard />,
document.getElementById('root'),
);
或者作为没有 React-Toolbox 的独立组件
class LiveImage extends React.Component {
constructor(props) {
super(props);
this.loadImage = () => {
const component = this;
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width =this.width;
canvas.height =this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(this, 0, 0);
var dataURL = canvas.toDataURL("image/png");
component.setState({liveImage: dataURL});
};
img.src = `${this.props.image}?${new Date().getTime()}`;
this.setState({ loadingImage: img });
}
this.state = {
loadingImage: null,
liveImage: null
};
}
componentDidMount() {
this.loadImage();
this.interval = setInterval(this.loadImage, this.props.interval);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<img src={this.state.liveImage} {...this.props} />
);
}
}
对我来说,删除 <Image>
道具,resizeMode={"contain"}
解决了 Android 上的闪烁问题。