Skip to main content
1 of 2
Taki
  • 608
  • 5
  • 11

For loop inside Render()

The loop gets called each time the component re-renders, it's a 1280 pushes to an array and that can be a performance issue, you can set it in componentDidMount or even outside the class since it's not dependent on its data,

Consider Array.from to create and fill the array without creating an intermediate one.

const range = Array.from({length: 1280}, (_, i) => i);

And since you're filling it with ints and the select value is an int you don't really need parseInt.

Using document.querySelector to read values

Basically, you can't easily rely on the input field because the state needs to come from the React app's state, not from the browser's idea of what the value should be.

See more explanation in this blog post.

You should instead use the state to store the values of the inputs. ( see code snippet below )

Accessing the DOM using document.querySelector

In React, we do not directly manipulate the actual DOM. Instead, we must manipulate the virtual representation and let React take care of changing the browser's DOM.

Check this article for in depth explanation and this one for different ways to access the DOM.

using refs, instead of doing document.querySelector('video'), you can add a ref like : <video src={video} controls ref={video => this.video = video}/> then use this.video to do what you would do with a regular html element.

Using html5 canvas with react

import React, { Component } from 'react';
import './App.css';
import video from './video.mp4';
import watermark from './watermark.png';

const range = Array.from({ length: 1280 }, (_, i) => i);

class App extends Component {
  constructor() {
    super();
    this.state = {
      select: 0,
      live: false,
      positionX: 0,
      positionY: 0,
      checked: false
    };
  }

  componentDidMount() {
    const context = this.canvas1.getContext('2d');
    context.drawImage(this.video, 0, 0, 720, 1280);
    context.drawImage(this.watermark, this.state.select, this.state.select);

    if (this.state.live) {
      this.setState({ image: canvas.toDataURL() });
    }
  }

  render() {
    return (
      <div className="app">
        <video src={video} controls ref={video => this.video = video} />
        <div>
          <div className="watermarkButton" style={{}}>

            <span className="watermarkButtonX">Watermark X
              <select
                className="positionX"
                onChange={value => this.setState({ select: value, positionX: value })}
                value={this.state.positionX}>
                {range.map(i => (
                  <option key={i} value={i}>{i}</option>
                ))}
              </select>
            </span>

            <span className="watermarkButtonY">Watermark Y
              <select
                className="positionY"
                onChange={value => this.setState({ select: value, positionY: value })}
                value={this.state.positionY}>
                >
                {range.map(i => (
                  <option key={i} value={i}>{i}</option>
                ))}
              </select>
            </span>

            <span>Live</span>
            <input
              type="checkbox"
              name="live"
              value={this.state.live}
              onChange={e => this.setState({ live: e.target.value })}
            />
          </div>


          <button className="watermarkButton watermarkSubmit"
            onClick={() => {
              const context = this.canvas2.getContext('2d');
              context.drawImage(this.video, 0, 0, 1280, 720);
              context.drawImage(this.watermark, this.state.positionX, this.state.positionY);
              this.setState({ image: canvas.toDataURL() });
            }}> Watermark! </button>

          <canvas ref={canvas => this.canvas1 = canvas} width={1280} height={720} />
          <canvas ref={canvas => this.canvas2 = canvas} width={1280} height={720} />

          <img
            alt="watermarks"
            className="watermark"
            src={watermark}
            style={{ visibility: 'visible' }}
            ref={watermark => this.watermark = watermark}
          />
          <img
            alt="watermarks"
            className="imageDisplay"
            height="405px"
            width="560px"
            src={this.state.image}
          />
        </div>
      </div>
    );
  }

}

export default App;
Taki
  • 608
  • 5
  • 11