konvajs / konva

Konva.js is an HTML5 Canvas JavaScript framework that extends the 2d context by enabling canvas interactivity for desktop and mobile applications.
http://konvajs.org/
Other
11.71k stars 933 forks source link

Mounted event #462

Closed fxdave closed 4 years ago

fxdave commented 6 years ago

Hi, currently the elements are not informed about when they were added to a layer.

When I am in an element context such as Konva.Group, I don't have access to the stage, so it will be good to have an event that inform the Konva.Group about it is added to a layer.

Moreover the elements should have other lifecycle events to ease our life, for e.g: mounted: when got layer and stage, updated: when the draw() called, deleted: when remove() called

fxdave commented 6 years ago

Example:

class Something extends Konva.Group {
     constructor() {
         this.rect = new Konva.Rect()
         this.add(this.rect)
         this.on("mounted",this.mounted.bind(this))
    }

    mounted() {
         //tweens or others
    }
}

Or it would be better if we just override a member named mounted:

class Something extends Konva.Group {
     constructor() {
         this.rect = new Konva.Rect()
         this.add(this.rect)
    }

    // override Konva.Node.mounted
    mounted() {
         //tweens or others
    }
}
lavrton commented 6 years ago

Looks like the style of virtual DOM frameworks (react, vue, angular). I don't think it is very helpful in Konva context.

Your code fully controls add, draw and remove methods. So if you need to do something on "mount" you can so this:

const shape = new Konva.Shape(props);
layer.add(shape);
// shape is added, do some "mount" logic
shape.to({
   opacity: 1
});
fxdave commented 6 years ago

I have tried the react-konva before but that was too restricting to me. My project couldn't be done in it.

I am using Konva in an object oriented way, for e.g:

class DeleteButton extends Konva.Group {
     constructor(proprs) {
           super(props)

           // A shape cannot be existed without shape, so all drawings go to the constructor
          this.bg = new Konva.Circle(...)
          this.text = new Konva.Text(...)

          this.add(this.bg,this.text)
          // so when I create a DeleteButton I get these shapes
          /*
          * it would be better if I could add styles here but Tween cannot be added without layer
          * I think it must be changed to "cannot be played without layer"
          * But create a mounted method is kind of good solution.
          */ 
     }

     mounted() {
            // add styles like hover animations
    }
}

class RemovableBox extends Konva.Group {
     constructor(props) {
         super(props)
          this.bg = new Konva.Rect(...)
          this.deleteButton = new DeleteButton()

          this.add(this.bg, this.deleteButton)
          //and now I have to notify deleteButton manually
          this.deleteButton.mounted()
    }
}

This way I have more freedom. React seems inefficient in canvas drawing to me. For e.g I have auto arrange script which working with the child elements too. this.arranger.add(removableBox) So I am using the javascript's great feature, I can pass a reference of a Konva.Group to the arranger object and that will do its job. React is for DOM like contexts. I think it just hides the great features of a canvas framework.

lavrton commented 4 years ago

Closing it for now, I am not sure we need this feature.