Coder Social home page Coder Social logo

Comments (2)

lavrton avatar lavrton commented on July 28, 2024

Please make a demo.

from react-konva.

rjungbeck avatar rjungbeck commented on July 28, 2024

I actually wrote a demo. But that was working correctly and helped me understand how Transformers (with multiple attached objects) work.

My orginal problem had to do with the way I handled onTransformEnd./ onDragEnd.

Maybe the documentation should describe that the events can be handled on ihe individual objects (even when using a Transformer to move or resize multiple objects). It also seems to be neccessary to reset scaleX and scaleY after during onEndtransform to 1

Here is my demo (as it might help others how it is supposed to work)

import React, {useState, useRef, useEffect} from "react";

import {Stage, Layer, Rect, Transformer, Group} from "react-konva";
import {Portal} from "react-konva-utils";

const initialConfigs = [
    {x: 0, y: 0, width: 100, height: 100, fill: "red", selected: false},
    {x: 200, y: 200, width: 100, height: 100, fill: "green", selected: false},
    {x: 400, y: 400, width: 100, height: 100, fill: "orange", selected: false},
    ];

const App = ({}) =>{
    const [configs, setConfigs] = useState(initialConfigs);

    const transformerRef = useRef();

    const handleUpdate = (index, values) => {
        console.log(index, values);
        setConfigs((oldConfigs) => {
            var newConfigs = structuredClone(oldConfigs);
            newConfigs[index] = {...newConfigs[index], ...values};
            return newConfigs;
            });
        }

    const handleOnlySelected = (newIndex) => {
        setConfigs((oldConfigs) => {
            var newConfigs = oldConfigs.map((config, index) => {
                return {...config, selected:index==newIndex};
                });
            return newConfigs;
            })
        }

    const boxes = configs.map((config, index) => {
        return <Box key={index} index={index} {...config} transformerRef={transformerRef} onUpdate={handleUpdate} onOnlySelected={handleOnlySelected}/>;
        });

    return  <div style= {{width: "95vw", height: "90vh", backgroundColor: "blue", overflow: "auto"}}>
                <Stage width={1000} height={1000}>
                    <Layer>
                        {boxes}
                        <Group name={"top"} />
                        <Transformer ref={transformerRef} />
                    </Layer>
                </Stage>
            </div>;
        }

const Box = ({transformerRef, index, selected, onUpdate, onOnlySelected,  ...rest}) => {
    const boxRef = useRef();

    const handleClick = () => {
        onUpdate(index,{selected: !selected});
        }

    const handleDragStart = (event) => {
        if (!selected) {
            onOnlySelected(index);
            }
        }

    const handleDragEnd = (event) => {
        const node = boxRef.current;
        onUpdate(index, {x: node.x(), y: node.y()});
        }

    const handleTransformEnd = (event) => {
        const node = boxRef.current;
        const newPos = {x: node.x(), y: node.y(), width: node.width() *node.scaleX(), height: node.height()*node.scaleY() };
        node.scaleX(1);
        node.scaleY(1);
        onUpdate(index, newPos);
        }

    useEffect(() => {
        var curNodes = transformerRef.current?.nodes();

        if (selected) {
            if (!curNodes.includes(boxRef.current)) {
                curNodes = [...curNodes, boxRef.current];
                transformerRef.current?.nodes(curNodes);
                }
            } else {
            if (curNodes.includes(boxRef.current)) {
                var curNodes = curNodes.filter((node) => node!=boxRef.current);
                transformerRef.current?.nodes(curNodes);
                }
            }
        }, [selected, transformerRef])

    console.log("Drawing", index, rest);

    return <Portal selector={".top"} enabled={selected}>
                <Rect ref={boxRef} {...rest} onClick={handleClick} draggable={true}  onTransformEnd={handleTransformEnd} onDragStart={handleDragStart} onDragEnd={handleDragEnd}/>
            </Portal>
    }

export default App;

from react-konva.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.