The cause of
Today, the product manager came to say that we need to add a rotation chart similar to tmall on the home page. The rotation chart of Tmall is the picture with fixed width and height. When the screen with different resolutions is displayed, the left and right gaps of the container will be filled according to the background color of the picture. For example, a 1800px screen:
3000 px screen:
First reaction: no matter js or CSS, there is no way to get the color value of the image, that must be the server to me. Either the background CMS specified the background color in the last image, or the server called the image API to get the background color and gave it to me.
That’s what Tmall should do.
AutoImg
Pure front-end, is there a way to get the color value? It occurred to me that when I was doing WebGL textures, I could get the color value of every pixel of the image in the pixel shader. WebGL is definitely too big to use, is Canvas ok? Query is ok, there are methods getImageData. So at least pure front-end cooking is possible. Let’s start with an AutoImg component. The img in AutoImg has a fixed height and width, and the container’s background color is filled with the IMG background color.
export default class AutoImg extends Component {
static propTypes = {
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
source: PropTypes.number.isRequired,
}
componentDidMount() {
this.setImg(this.props.source)
}
componentWillReceiveProps(nextProps) {
if(nextProps.source ! = =this.props.source) {
this.setImg(nextProps.source)
}
}
setImg(source) {
const { width, height } = this.props
const ima = new Image()
ima.src = source
ima.crossOrigin = ' ' // Handle cross-domain images
ima.onload = (a)= > {
const ctx = this.canva.getContext('2d')
ctx.drawImage(ima, 0.0, width, height)
const [r, g, b, a] = ctx.getImageData(0.0.1.1).data; // Get the background color
this.inner.style.background = `rgba(${r}.${g}.${b}.${a}) `
}
}
render() {
const { width, height } = this.props
return (
<div ref={inner= > this.inner = inner}>
<canvas
style={{
display: 'block',
margin: '0 auto'}}width={` ${width}px`}
height={` ${height}px`}
ref={canva= > this.canva = canva}
>
</canvas>
</div>)}}Copy the code
GetImageData is an integer. Width and height must be of type number. 1000 means 1000px
github npm: npm install rc-autoimg --save
shuffling
We don’t make wheels, we just use nuka-Carousel.
import Carousel from 'nuka-carousel'
default class Banner extends Component {
render() {
const bannerImgList = [
'https://img.alicdn.com/tps/i4/TB1yqAhcpmWBuNjSspdSuvugXXa.jpg'.'https://img.alicdn.com/tps/i4/TB1XVCsaTdYBeNkSmLySutfnVXa.jpg'.'https://img.alicdn.com/simba/img/TB1ror0cf5TBuNjSspcSuvnGFXa.jpg'.'https://img.alicdn.com/tfs/TB1ed2lggmTBuNjy1XbXXaMrVXa-1130-500.jpg_q100.jpg_.webp',]return (
<div className={styles.banner}>
<Carousel
autoplay={true}
>
{
bannerImgList.map(source => (
<div key={source}>
<AutoImg
width={1200}
height={340}
source={source}
/>
</div>))}</Carousel>
</div>)}}Copy the code
2500 px effect:
conclusion
Perhaps you also have this kind of rotation needs, if there is no hope to extract the color of the place, can inspire you.