Can you use new Image() inside the Next.js? I am getting error, saying it is not defined.
I know I can simply use inside JSX, but in this case, I am not sure if it will work, as I must reference the image outisde JSX, as shown below.
If there is no way to make new Image() work with Next.js, please show a different way to make this work. This new Image() is for making a GSAP scroll animation work.
Here is my code:
import Link from 'next/link'
import Head from 'next/head'
import Image from 'next/image'
import {useEffect, useRef, useState} from 'react'
import styles from '../styles/Home.module.css'
import {gsap} from 'gsap'
import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
const Home = () => {
const viewer = useRef(null)
const image = new Image();
if (typeof window !== "undefined") {
gsap.registerPlugin(ScrollTrigger);
}
useEffect(()=>{
const rows = 5
const columns = 10
const frame_count = rows * columns - 1
// const imageWidth = 6336
// const imageHeight = 1782
const imageWidth = 4049
const imageHeight = 3000
const horizDiff = imageWidth / columns
const vertDiff = imageHeight / rows
const ctx = viewer.current.getContext("2d");
viewer.current.width = horizDiff;
viewer.current.height = vertDiff;
const image = new Image()
image.src = "./spriteDesk.jpg";
// image.src = "./spriteMobile.jpg";
image.onload = () => onUpdate();
const setPos = gsap.quickSetter(viewer.current, "background-position");
const obj = {num: 0};
gsap.to(obj, {
num: frame_count,
ease: "steps(" + frame_count + ")",
scrollTrigger: {
trigger: ".section-one",
start: "top top",
end: "+=" + imageHeight,
pin: true,
anticipatePin: 1,
scrub: 1
},
onUpdate
});
function onUpdate() {
ctx.clearRect(0, 0, horizDiff, vertDiff);
const x = Math.round((obj.num % columns) * horizDiff);
const y = Math.round(Math.floor(obj.num / columns) * vertDiff);
ctx.drawImage(image, x, y, horizDiff, vertDiff, 0, 0, horizDiff, vertDiff);
}
},[])
return (
<>
<Head>
<title>TalkingSkunk | Home</title>
<meta name='keywords' content='talkingskunk' />
<link rel="icon" href="/favicon.ico" />
{/* <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.6.1/ScrollTrigger.min.js"></script> */}
</Head>
{/* <div className={styles.bgWrap}>
<Image
src="/spriteDesk.png"
className='cityscape'
data-speed="0.2"
layout="fill"
objectFit="cover"
quality={100}
/> */}
{/* <Image src ='/spriteDesk.jpg' alt="spriteDesk" width ={4049} height = {3000} /> */}
{/* <p className={styles.bgText}>
Discover
</p> */}
<section className="styles.scene styles.section section-one">
<canvas ref={viewer} className="styles.viewer"></canvas>
</section>
</>
)
}
export default Home;
If anyone still needs this it can be accomplished by following the next steps:
import Image from 'next/image' with import NextImage from 'next/image' (or anything similar),<Image ... tags with <NextImage ... (or, if you don't have any, than just remove the import)Image() constructor to create a new HTMLImageElement instance described on mdn page.Next.js version 11+ (or earlier) use one of the solutions described on this question to disable no-img-element lint in order to prevent the error.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With