Reputation: 13
How would I write this Typescript code in Javascript?
function ImageMagnifier({
src,
width,
height,
magnifierHeight = 100,
magnifieWidth = 100,
zoomLevel = 1.5
}: {
src: string;
width?: string;
height?: string;
magnifierHeight?: number;
magnifieWidth?: number;
zoomLevel?: number;
}) {
const [[x, y], setXY] = useState([0, 0]);
const [[imgWidth, imgHeight], setSize] = useState([0, 0]);
const [showMagnifier, setShowMagnifier] = useState(false);
I found the code here https://codesandbox.io/s/image-magnifier-3jsqs?from-embed=&file=/src/App.tsx:77-498
but i am getting errors when i use it in a jsx file because its typescript.
the part in particular its having issues with is
src: string;
width?: string;
height?: string;
magnifierHeight?: number;
magnifieWidth?: number;
zoomLevel?: number;
UPDATE:
I tried the code in the first answer and the error is gone and the magnifier seems to work except that I get broken images. see attached image
When i check my console i see that the src=[object Object] - see attached image
my ImageMagnifier React component code:
import { useEffect, useRef, useState } from "react";
function ImageMagnifier(
src,
width,
height,
magnifierHeight = 100,
magnifieWidth = 100,
zoomLevel = 1.5
)
{
const [[x, y], setXY] = useState([0, 0]);
const [[imgWidth, imgHeight], setSize] = useState([0, 0]);
const [showMagnifier, setShowMagnifier] = useState(false);
return (
<div
style={{
position: "relative",
height: height,
width: width
}}
>
<img
src={src}
style={{ height: height, width: width }}
onMouseEnter={(e) => {
// update image size and turn-on magnifier
const elem = e.currentTarget;
const { width, height } = elem.getBoundingClientRect();
setSize([width, height]);
setShowMagnifier(true);
}}
onMouseMove={(e) => {
// update cursor position
const elem = e.currentTarget;
const { top, left } = elem.getBoundingClientRect();
// calculate cursor position on the image
const x = e.pageX - left - window.pageXOffset;
const y = e.pageY - top - window.pageYOffset;
setXY([x, y]);
}}
onMouseLeave={() => {
// close magnifier
setShowMagnifier(false);
}}
alt={"img"}
/>
<div
style={{
display: showMagnifier ? "" : "none",
position: "absolute",
// prevent maginier blocks the mousemove event of img
pointerEvents: "none",
// set size of magnifier
height: `${magnifierHeight}px`,
width: `${magnifieWidth}px`,
// move element center to cursor pos
top: `${y - magnifierHeight / 2}px`,
left: `${x - magnifieWidth / 2}px`,
opacity: "1", // reduce opacity so you can verify position
border: "1px solid lightgray",
backgroundColor: "white",
backgroundImage: `url('${src}')`,
backgroundRepeat: "no-repeat",
//calculate zoomed image size
backgroundSize: `${imgWidth * zoomLevel}px ${
imgHeight * zoomLevel
}px`,
//calculete position of zoomed image.
backgroundPositionX: `${-x * zoomLevel + magnifieWidth / 2}px`,
backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`
}}
></div>
</div>
);
}
export default ImageMagnifier;
// export default function App() {
// return (
// <div className="App">
// <ImageMagnifier
// width={"200px"}
// src="https://images-na.ssl-images-amazon.com/images/I/616HiOFb1VL._AC_UX679_.jpg"
// />
// </div>
// );
// }
my code where I output the images
import useStore from "../../../store";
import { useEffect, useState } from 'react';
import Image from 'next/image';
import ImageMagnifier from "../../image/ImageMagnifier";
const Thread = ({thread}) => {
const threadColor = useStore(state => state.threadColor);
const setThreadColor = useStore(state => state.setThreadColor);
const threadFeature = useStore(state => state.threadFeature);
const setThreadFeature = useStore(state => state.setThreadFeature);
const change = (e)=> {
setThreadColor(e.target.dataset.name);
setThreadFeature(e.target.dataset.feature);
}
return (
<div>
<ImageMagnifier
width={"400px"}
src="https://images-na.ssl-images-amazon.com/images/I/616HiOFb1VL._AC_UX679_.jpg"
>
</ImageMagnifier>
{/*
// <Image
// style={{
// borderRadius: '50px'
// }}
// onMouseEnter={() => setIsShown(true)}
// onMouseLeave={() => setIsShown(false)}
// onClick={change}
// data-name={thread?.name}
// data-feature={thread?.threadFields?.threadFeature}
// src={thread?.threadFields?.threadImage?.sourceUrl ?? //''}
// alt={ thread?.threadFields?.threadImage?.altText ?? //'' }
// title={ thread?.threadFields?.threadImage?.title ?? //''}
// width="100"
// height="50"
/> */}
</div>
);
};
export default Thread;
the code where i get the grapghql data:
import { useQuery, gql } from '@apollo/client';
import { isEmpty } from 'lodash';
import Thread from './Thread';
const THREADS_QUERY = gql ` query {
threads {
nodes {
name
threadFields {
threadColor
threadFeature
threadImage {
sourceUrl
title
altText
}
}
}
}
}`;
function DisplayThreads() {
const { loading, error, data } = useQuery(THREADS_QUERY);
console.log('data:',data);
if (isEmpty ( data )){
return null;
}
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return (
<>
{data.threads.nodes.map((thread, i) => (
<Thread key={i} thread={thread}/>
))}
</>
)
}
const ThreadColors = () => {
return (
<>
<h3>Select Symbol Colour</h3>
<div className="d-flex">
<DisplayThreads/>
</div>
</>
);
};
export default ThreadColors;
at first I thought ImageMagnifier had an issue with my image src given that it is generated from a graphql fetch however when i use the image from the original code (which is a live working image - https://images-na.ssl-images-amazon.com/images/I/616HiOFb1VL._AC_UX679_.jpg ) I still get the broken images result ( src=[object Object])
would really appreciate help to figure this out
Upvotes: 0
Views: 93
Reputation: 64
You can write in this way.
function ImageMagnifier(
src,
width,
height,
magnifierHeight = 100,
magnifieWidth = 100,
zoomLevel = 1.5
)
Upvotes: 0
Reputation: 5381
Just remove the whole
: {
src: string;
width?: string;
height?: string;
magnifierHeight?: number;
magnifieWidth?: number;
zoomLevel?: number;
}
Upvotes: 3