0

I have been having this issue using react-konva were when I remove a shape within the array all shapes move to initial position and if the shape is placed in one position above the deleted one and has the same component name for e.g: deleted === RegularPolygon and one just above===RegularPolygon, than it takes the same position of the deleted component as well as the same size and rotation. I have tried changing the index to the furthest position on delete and also tried splicing to remove and place at the top of the array but it's still not working. Using strictMode makes the shape bigger on delete and doesn't keep its initial size. I just want all shapes to keep the same position, size, and rotation when deleting a shape from the array, How can I do that?

the code is quite big but here are the concerned chunks:

parent states:

constructor(props){
    super(props)
    //this.animationDeleteInheritance = React.createRef();
    this.state={
        chosenSelectedCategory:"",
        animations:false,
        chooseColor:"",
        paused:true,
        timerString:"00",
        timer: 0,
        colorPicker:false,
        selectedDestinationID:"",
        selectedRouteID:"",
        selectedElementsID:"",
        selectedType:"",
        elements:[],
        destinations:[],
        routes:[],
        travelers:[],
        konva:false
        //final destination
    }
}

remove element:

removeElements = () =>{

    //this.animationDeleteInheritance.current.animationInheritance()
    console.log(this.state.selectedType)
 //  let s=[] 
let r=[]
for(let i = 0; i<this.state.elements.length; i++){
  /*  
   if(this.state.selectedElementsID !=='' && this.state.elements[i].id === this.state.selectedElementsID) 
   {s.push(this.state.elements[i]);
    this.state.elements.splice(i,1);
    this.state.elements.splice(this.state.elements.length,0, s)
    }*/
if(this.state.selectedElementsID !=='' && this.state.elements[i].id !== this.state.selectedElementsID) 
    {r.push(this.state.elements[i])}
  //  console.log( Math.max(...this.state.routes[i].id))


}

Stage Layer:

<div class="designScreen"  >

<Stage

width={window.innerWidth*4/5}
height={window.innerHeight*8.65/10}
onClick={this.getKonvaChildren}
onMouseDown={this.activateRouteTrigger} onMouseUp={this.deactivateRouteTrigger}  onDragMove={this.updateRoute}
>

<Layer onClick={this.getKonvaChildren}

>


{
                  this.state.elements.map((el) => {
                    return <Content id={el.id}
                                    element={el.element}
                                    color={el.color}
                                    title={el.title}
                                    type={el.type}
                                    rY={el.rY}
                                    rX={el.rX}
                                    sX={el.sX}
                                    sY={el.sY}
                                    zIndex={el.zIndex}
                                    konvaTrigger={this.konvaTrigger}
                                    elements={this.state.elements}
                                    visibilityStatus={el.visibilityStatus}
                                    selectType={this.selectType}
                                    parentCallback = {this.selectDestinations}
                                    selectedDestinationID = {this.state.selectedDestinationID}
                                    destinations={this.state.destinations}
                                    parentCallbackColor = {this.changeColorSelector}
                                    timerString={this.state.timerString}
                                    elementsID={this.selectElements}
                                    selectedRouteID={this.state.selectedRouteID}
                                    selectedElementsID={this.state.selectedElementsID}
                                    selectedRouteIDParentCallback={this.updateselectedRouteID}
                                    updateRouteX={this.updateRouteX}
                                    updateRouteY={this.updateRouteY}
                                    updateRoutePosition={this.updateRoutePosition}



                    /> 

                  })
              }  





</Layer>
</Stage>
</div>

child component render and return:

render(){





const polygon=  this.props.id===this.props.selectedElementsID ?  <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<RegularPolygon
id="konva"


    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={60}
height={90}
ref={node => {
    this.polygon = node;

  }}
sides= {6} //3 for Triangle

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}

dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
<Transformer
        ref={node => {
          this.transformer = node;
        }}
      />

</Group>
:
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<RegularPolygon
id="konva"


    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={60}
height={90}

sides= {6} //3 for Triangle

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}

dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
</Group>


const triangle=  this.props.id===this.props.selectedElementsID ?  <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<RegularPolygon
id="konva"
ref={node => {
    this.polygon = node;
  }}

    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={60}
height={90}

sides= {3} //3 for Triangle

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
<Transformer
        ref={node => {
          this.transformer = node;
        }}
      />

</Group>
:
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<RegularPolygon
id="konva"


    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={60}
height={90}

sides= {3} //3 for Triangle

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>


</Group>

const rectangle=  this.props.id===this.props.selectedElementsID ?  <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Rect
id="konva"

ref={node => {
    this.polygon = node;
  }}
    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={100}
height={60}



fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
<Transformer
        ref={node => {
          this.transformer = node;
        }}
      />
</Group>
:
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Rect
id="konva"


    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={100}
height={60}



fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>

</Group>


const borderRectangle=  this.props.id===this.props.selectedElementsID ?  <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Rect
id="konva"
ref={node => {
    this.polygon = node;
  }}

    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={100}
height={60}
cornerRadius= {8}


fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
<Transformer
        ref={node => {
          this.transformer = node;
        }}
      />
</Group>
:
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Rect
id="konva"


    pointerLength={20} 
   draggable="true"
pointerWidth={20} 

x= {300}
y= {200}
width={100}
height={60}
cornerRadius= {8}


fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {4}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>

</Group>

const oval=   this.props.id===this.props.selectedElementsID ? <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Ellipse
id="konva"
ref={node => {
    this.polygon = node;
  }}

   draggable="true"


x= {300}
y= {200}
width={80}
height={80}

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {40}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>
<Transformer
        ref={node => {
          this.transformer = node;
        }}
      />
</Group>
:
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} >
<Ellipse
id="konva"


   draggable="true"


x= {300}
y= {200}
width={80}
height={80}

fill= {this.props.color}
//stroke= 'black'
//strokeWidth= {40}
visible={this.props.visibilityStatus===false ? false :true}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }

/>

</Group>


const line=    <Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks}  >

<Line id="konva"  

points={[this.props.rX,this.props.rY,this.props.sX,this.props.sY]} 


visible={this.props.visibilityStatus===false ? false :true}
 fill={`${this.props.color}`} 
stroke={`${this.props.color}`}  
strokeWidth={2.5}
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*70/10 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  } />
<Rect 
id="r"
ref={node => {
    this.pointR = node;
  }}

//zIndex={1} 
draggable="true"
cornerRadius= {2}
x={this.props.rX -5}
y={this.props.rY - 5}
 width={10} 
 height={10} 
fill="green"
 visible={this.props.visibilityStatus===false || this.props.selectedElementsID !== this.props.id ? false :true}>
 </Rect>
 <Rect 
   ref={node => {
    this.pointS = node;
  }}
 id="s"
// zIndex={1} 
 draggable="true"

cornerRadius= {2}
x={this.props.sX -5}
y={this.props.sY - 5}
 width={10} 
 height={10} 
 fill="green"
 visible={this.props.visibilityStatus===false || this.props.selectedElementsID !== this.props.id ? false :true}>
 </Rect>
</Group>

const arrow=  
<Group zIndex={this.props.zIndex} onMouseDown={this.parentsCallBacks} onMouseUp={this.parentsCallBacks} onClick={this.parentsCallBacks} zIndex={this.props.elements.length -1}  >
<Arrow
points={[this.props.rX,this.props.rY,this.props.sX,this.props.sY]} 
pointerLength={10} 
pointerWidth={10} 
id="konva" fill={`${this.props.color}`} 
visible={this.props.visibilityStatus===false ? false :true}
stroke={`${this.props.color}`} 
 strokeWidth={2.5} 
dragBoundFunc={ pos=> {
    var Ylimit=pos.y > window.innerHeight*8.65/10 ? window.innerHeight*8.65/10 : pos.y
    var Xlimit=pos.x > window.innerWidth*4/5 ? window.innerWidth*4/5 : pos.x
    return {
      x: pos.x,
      y: pos.y
    };}
  }/>
  <Rect 
  id="r"
  ref={node => {
    this.pointR = node;
  }}
  //zIndex={1} 

cornerRadius= {2}
x={this.props.rX - 5}
y={this.props.rY - 5}
 width={10} 
 height={10} 
 draggable={true} fill="green"
 visible={this.props.visibilityStatus===false || this.props.selectedElementsID !== this.props.id ? false :true}>
 </Rect>
 <Rect 
 id="s"
 ref={node => {
    this.pointS = node;
  }}
 //zIndex={1} 

cornerRadius= {2}
x={this.props.sX -5}
y={this.props.sY - 5}
 width={10} 
 height={10} 
 draggable={true} fill="green"
 visible={this.props.visibilityStatus===false || this.props.selectedElementsID !== this.props.id ? false :true}>
 </Rect>
 </Group>




        return(

            this.props.element==="line" ? line : this.props.element==="polygon" ? polygon : 
            this.props.element==="triangle" ? triangle : this.props.element==="rectangle" ? rectangle :
            this.props.element==="Oval" ? oval : 
            this.props.element==="border rectangle" ? borderRectangle :arrow




        )
    }

    }

I would be glad to show a demo using skype, slack or any other screen sharing platform. Thanks

Camille Basbous
  • 299
  • 5
  • 11
  • 34

1 Answers1

2

It is possible that you are not using key attribute correctly.

You can read more about it here: https://reactjs.org/docs/lists-and-keys.html

In short, just make sure each element in your state has uniq id. Then use that id for key attribute:

this.state.elements.map((el) => { return <Element key={el.id} {...otherProps} />});

Also take a look into this demo: https://konvajs.org/docs/react/zIndex.html

lavrton
  • 18,973
  • 4
  • 30
  • 63