In React, swap images on scroll; a la

Update: Code below’s updated. Seems to be working, although, it ain’t pretty. Still, a start. If anyone looks this over and has a thought or two, feel free… Appreciate the attention.

I’m working on a small site, using React 16.3.2.

My site riffs off the homepage of Its hero image is replaced by a second image with a cutout as users scroll down. This is what I’m currently trying to approximate.

I’ve added two (dummy) images to my / route Component. The first image is actual size, the second image is scaled up off the page via a CSS transform: scale(x, y) attribute. This image should scale down to actual size as the user scrolls down the page. The first and second images are in a fixed-position <div>, so the page doesn’t “move” when scrolling. The height of this <div> is currently 4000px (arbitrary, can be smaller).

I now need to track the scroll position of the page, or rather the scrollable div, and call a function that alters my transform attribute as it moves. (At the bottom, I’ll need to bring in three more divs to break the page up into three clickable sections that will take the user to new sections of the site via a browserRouter.)

This seems easier said than done. Call me a novice.

I’ve looked at plenty of tutorials, including Kirupa’s, which are among the clearest I’ve found. But wiring this up properly in the context of React, versus a script, is currently getting the best of me. The details of wiring up unusual scroll events don’t seem to be a hot topic, which makes it a good way to tell a story on-site.

My current Component is below, with a few false starts baked in. Any help or guidance appreciated. Conceptual points as to event handlers in React is helpful, too. Happy to include more info or alter what I’ve done to suit anyone’s thoughts. In theory, I don’t think this should be too hard, but, tada…

import React, { Component } from 'react';
import ParTestImg from './ParTestImg.jsx';
import SiteHeader from './SiteHeader.jsx';
import Footer from './Footer.jsx';

var background = '/test/pngtree-magskyline.jpg';
var background2 = '/test/beaker-magic-2.png';

var wrapperStyle = {
  width: '100%',
  position: 'fixed'

var scrollerStyle = {
  height: '4000px'

var topImgStyle = {
  position: 'relative'

class ParTest extends Component {
  constructor(props) {
    this.state = {
      xScale: 6,
      yScale: 6

    this.handleScroll = this.handleScroll.bind(this);
    this.parThis = this.parThis.bind(this);

  componentDidMount() {
        window.addEventListener('scroll', this.parThis);

  componentWillUnmount() {
        window.removeEventListener('scroll', this.parThis);

  handleScroll(event) {

  parThis(event) {
        var scrollTop = window.pageYOffset;
        var oldPercent = (scrollTop - 0) / (4000 - 0);
        var numberForScale = 6/(((7 - 1) * oldPercent) + 1);

        this.setState({ xScale: numberForScale })
        this.setState({ yScale: numberForScale })

  render() {
        var btmImgStyle = {
              position: 'absolute',
              transform: 'scale(' + this.state.xScale + ',' + this.state.yScale + ')',
              top: '0',
              right: '0'

    return (
        <div id='PTOuterDiv' style={wrapperStyle} >
          <SiteHeader />
          <div id='PTInnerDiv' >
            <div id='PTTopImg' style={topImgStyle} >
              <img src={background} alt='b' />
            <div id='PTBottomImg' style={btmImgStyle} >
              <img src={background2} alt='b2' />
        <div id='PTScrollerDiv' style={scrollerStyle} ref={element => this.scrollerRef = element} onScroll={this.handleScroll} onScroll={this.parThis} >


export default ParTest;

Thanks much.