Skip to content

Commit

Permalink
Update z-index for canvas and player page
Browse files Browse the repository at this point in the history
  • Loading branch information
maximvl committed Sep 29, 2024
1 parent 0bacece commit 57fb267
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 111 deletions.
184 changes: 94 additions & 90 deletions src/components/PlayerCanvasBackground/ui/canvas-stage.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,61 @@
import React, { useEffect, useRef } from 'react';
import { CanvasImage, usePlayerCanvasBackgroundContext } from '../context';
import Konva from 'konva';
import { Image as KonvaImage, Layer, Stage, Transformer } from 'react-konva';
import useImage from 'use-image';
import { KonvaEventObject } from 'konva/lib/Node';

const URLImage = ({ image, setImages }: {
image: CanvasImage;
setImages: React.Dispatch<React.SetStateAction<CanvasImage[]>>;
import React, { useEffect, useRef } from 'react'
import { CanvasImage, usePlayerCanvasBackgroundContext } from '../context'
import Konva from 'konva'
import { Image as KonvaImage, Layer, Stage, Transformer } from 'react-konva'
import useImage from 'use-image'
import { KonvaEventObject } from 'konva/lib/Node'

const URLImage = ({
image,
setImages,
}: {
image: CanvasImage
setImages: React.Dispatch<React.SetStateAction<CanvasImage[]>>
}) => {
const { url, id, scaleX, scaleY, zIndex, ...restProps } = image;
const { url, id, scaleX, scaleY, zIndex, ...restProps } = image

const { selectedImage, setSelectedImage, setFlipFunction } = usePlayerCanvasBackgroundContext();
const { selectedImage, setSelectedImage, setFlipFunction } =
usePlayerCanvasBackgroundContext()

const [img, loadState] = useImage(`${image.url}`);
const imageRef = React.useRef<Konva.Image>(null);
const trRef = useRef<Konva.Transformer>(null);
const [img, loadState] = useImage(`${image.url}`)
const imageRef = React.useRef<Konva.Image>(null)
const trRef = useRef<Konva.Transformer>(null)

useEffect(() => {
if (imageRef.current === null) {
console.log('imageRef.current is null');
return;
console.log('imageRef.current is null')
return
}
if (trRef.current === null) {
console.log('trRef.current is null');
return;
console.log('trRef.current is null')
return
}

trRef.current?.nodes([imageRef.current]);
trRef.current?.getLayer()?.batchDraw();
}, [trRef.current, imageRef.current]);
trRef.current?.nodes([imageRef.current])
trRef.current?.getLayer()?.batchDraw()
}, [trRef.current, imageRef.current])

const updateImages = (img: CanvasImage) => {
console.log('updateImages()');
setImages((prevImages) => ([
...prevImages.filter(i => i.id !== id),
img,
]));
};
console.log('updateImages()')
setImages((prevImages) => [...prevImages.filter((i) => i.id !== id), img])
}

const flipImage = () => {
console.log('flipImage()');
const node = imageRef.current;
console.log('flipImage()')
const node = imageRef.current
if (node) {
const newScaleX = node.scaleX() * -1;
let rotation = node.rotation();
const newScaleX = node.scaleX() * -1
let rotation = node.rotation()

console.log('old node.scaleX()', node.scaleX());
console.log('old node.scaleY()', node.scaleY());
console.log('old node.scaleX()', node.scaleX())
console.log('old node.scaleY()', node.scaleY())

node.scaleX(newScaleX);
node.scaleX(newScaleX)

console.log('new node.scaleX()', node.scaleX());
console.log('new node.scaleY()', node.scaleY());
console.log('new node.scaleX()', node.scaleX())
console.log('new node.scaleY()', node.scaleY())

console.log('old image', selectedImage);
console.log('old image', selectedImage)

const updatedImage = {
...image,
Expand All @@ -65,56 +66,56 @@ const URLImage = ({ image, setImages }: {
rotation,
width: node.width(),
height: node.height(),
};
}

console.log('updatedImage', updatedImage);
console.log('updatedImage', updatedImage)

updateImages(updatedImage);
updateImages(updatedImage)
}
};
}

const selectImage = (img: CanvasImage) => {
setFlipFunction(flipImage);
setSelectedImage(img);
};
setFlipFunction(flipImage)
setSelectedImage(img)
}

const handleDragEnd = (e: KonvaEventObject<DragEvent>) => {
console.log('handleDragEnd()');
console.log('handleDragEnd()')
const updatedImage = {
...image,
x: e.target.x(),
y: e.target.y(),
};
}

updateImages(updatedImage);
selectImage(updatedImage);
};
updateImages(updatedImage)
selectImage(updatedImage)
}

const handleTransformEnd = () => {
console.log('handleTransformEnd()');
console.log('handleTransformEnd()')
// transformer is changing scale of the node
// and NOT its width or height
// but in the store we have only width and height
// to match the data better we will reset scale on transform end
const node = imageRef.current;
const node = imageRef.current
if (node) {
const transformScaleX = node.scaleX();
const transformScaleY = node.scaleY();
const transformScaleX = node.scaleX()
const transformScaleY = node.scaleY()

console.log('node.scale()', node.scale());
console.log('node.scale()', node.scale())

console.log('old scaleX', transformScaleX);
console.log('old scaleY', transformScaleY);
console.log('old scaleX', transformScaleX)
console.log('old scaleY', transformScaleY)

const newScaleX = transformScaleX > 0 ? 1 : -1;
const newScaleY = transformScaleY > 0 ? 1 : -1;
const newScaleX = transformScaleX > 0 ? 1 : -1
const newScaleY = transformScaleY > 0 ? 1 : -1

// we will reset it back
node.scaleX(newScaleX);
node.scaleY(newScaleY);
node.scaleX(newScaleX)
node.scaleY(newScaleY)

console.log('new scaleX', node.scaleX());
console.log('new scaleY', node.scaleY());
console.log('new scaleX', node.scaleX())
console.log('new scaleY', node.scaleY())

const updatedImage = {
...image,
Expand All @@ -125,14 +126,14 @@ const URLImage = ({ image, setImages }: {
y: node.y(),
scaleX: newScaleX,
scaleY: newScaleY,
};
}

console.log('updatedImage', updatedImage);
console.log('updatedImage', updatedImage)

updateImages(updatedImage);
selectImage(updatedImage);
updateImages(updatedImage)
selectImage(updatedImage)
}
};
}

return (
<>
Expand All @@ -142,8 +143,8 @@ const URLImage = ({ image, setImages }: {
{...restProps}
draggable
onClick={() => {
console.log('image clicked', image);
selectImage(image);
console.log('image clicked', image)
selectImage(image)
}}
onDragEnd={handleDragEnd}
onTransformEnd={handleTransformEnd}
Expand All @@ -157,9 +158,9 @@ const URLImage = ({ image, setImages }: {
boundBoxFunc={(oldBox, newBox) => {
// limit resize
if (Math.abs(newBox.width) < 5 || Math.abs(newBox.height) < 5) {
return oldBox;
return oldBox
}
return newBox;
return newBox
}}
borderStroke={selectedImage?.id === id ? 'magenta' : undefined}
borderStrokeWidth={selectedImage?.id === id ? 2 : 1}
Expand All @@ -168,17 +169,23 @@ const URLImage = ({ image, setImages }: {
anchorCornerRadius={50}
/>
</>
);
};

export function CanvasStage({ imageList, setImageList, width, height }: {
imageList: CanvasImage[];
setImageList: React.Dispatch<React.SetStateAction<CanvasImage[]>>;
width: number;
height: number;
)
}

export function CanvasStage({
imageList,
setImageList,
width,
height,
}: {
imageList: CanvasImage[]
setImageList: React.Dispatch<React.SetStateAction<CanvasImage[]>>
width: number
height: number
}) {
const { setSelectedImage, setFlipFunction } = usePlayerCanvasBackgroundContext();
const stageRef = useRef<Konva.Stage>(null);
const { setSelectedImage, setFlipFunction } =
usePlayerCanvasBackgroundContext()
const stageRef = useRef<Konva.Stage>(null)

return (
<>
Expand Down Expand Up @@ -217,24 +224,21 @@ export function CanvasStage({ imageList, setImageList, width, height }: {
position: 'absolute',
border: '1px solid cyan',
overflow: 'hidden',
zIndex: 20,
}}
onClick={(e) => {
if (e.target === stageRef.current) {
setSelectedImage(null);
setFlipFunction(null);
setSelectedImage(null)
setFlipFunction(null)
}
}}
>
<Layer>
{imageList.map((image) => (
<URLImage
key={image.id}
image={image}
setImages={setImageList}
/>
<URLImage key={image.id} image={image} setImages={setImageList} />
))}
</Layer>
</Stage>
</>
);
)
}
61 changes: 41 additions & 20 deletions src/components/PlayerCanvasBackground/ui/static-canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,65 @@
import React from 'react';
import { Box } from '@mui/material';
import { usePlayerCanvasBackgroundContext } from '../context';
import React from 'react'
import { Box } from '@mui/material'
import { usePlayerCanvasBackgroundContext } from '../context'

function rotateImage(x: number, y: number, width: number, height: number, angle: number, scaleX: number, scaleY: number) {
function rotateImage(
x: number,
y: number,
width: number,
height: number,
angle: number,
scaleX: number,
scaleY: number
) {
if (angle < 0) {
angle = 360 + angle;
angle = 360 + angle
}

// Convert degrees to radians
const theta = angle * (Math.PI / 180);
const theta = angle * (Math.PI / 180)

// Calculate the new position for rotation
let newX = x - (width / 2) * (1 - Math.cos(theta)) - (height / 2) * Math.sin(theta);
let newY = y - (height / 2) * (1 - Math.cos(theta)) + (width / 2) * Math.sin(theta);
let newX =
x - (width / 2) * (1 - Math.cos(theta)) - (height / 2) * Math.sin(theta)
let newY =
y - (height / 2) * (1 - Math.cos(theta)) + (width / 2) * Math.sin(theta)

// Adjust for mirroring
if (scaleX === -1) {
// When mirroring, we need to shift the x position based on the rotation angle
newX -= width * Math.cos(theta); // Adjust for width based on rotation
newY -= height * Math.sin(theta); // Adjust for height based on rotation
newX -= width * Math.cos(theta) // Adjust for width based on rotation
newY -= height * Math.sin(theta) // Adjust for height based on rotation
}
if (scaleY === -1) {
newX += width * Math.sin(theta);
newY -= height * Math.cos(theta);
newX += width * Math.sin(theta)
newY -= height * Math.cos(theta)
}

// Return the transformed coordinates
return { x: newX, y: newY };
return { x: newX, y: newY }
}

export function StaticCanvas() {
const { images } = usePlayerCanvasBackgroundContext();
const { images } = usePlayerCanvasBackgroundContext()

return (
<Box sx={{
position: 'absolute',
backgroundColor: 'yellow',
}}>
<Box
sx={{
position: 'absolute',
backgroundColor: 'yellow',
zIndex: 0,
}}
>
{images.map((image) => {
const { x, y } = rotateImage(image.x, image.y, image.width, image.height, image.rotation, image.scaleX, image.scaleY);
const { x, y } = rotateImage(
image.x,
image.y,
image.width,
image.height,
image.rotation,
image.scaleX,
image.scaleY
)

return (
<Box
Expand All @@ -56,7 +77,7 @@ export function StaticCanvas() {
}}
draggable={false}
/>
);
)
})}
</Box>
)
Expand Down
2 changes: 1 addition & 1 deletion src/pages/player/components/PlayerContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function PlayerContent(props: Props) {

return (
<PlayerCanvasBackground player={player} canEdit={canEdit}>
<Box marginTop={'100px'}>
<Box marginTop={'100px'} position={'relative'} zIndex={5}>
<Box textAlign={'center'}>
<Typography fontSize="48px" fontWeight={700}>
Страница участника {player.name}
Expand Down

0 comments on commit 57fb267

Please sign in to comment.