Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features that I am currently missing #225

Closed
mihhail-lapushkin opened this issue Jan 12, 2013 · 9 comments
Closed

Features that I am currently missing #225

mihhail-lapushkin opened this issue Jan 12, 2013 · 9 comments

Comments

@mihhail-lapushkin
Copy link
Contributor

Hi,

While working on a project using KineticJS I've collected a bunch of extensions that I've created for myself. Would be nice to include them into the library.

Convenience methods for Containers

prototype.isEmpty = function() {
    return this.getChildren().length === 0;
};

prototype.size = function() {
    return this.getChildren().length;
};

prototype.each = function(fn) {
    this.getChildren().forEach(fn); // for library the loop might be better for compatibility reasons
};

toLocal and toGlobal methods (like in ActionScript)

Here is my code for Container:

prototype._toCoord = function(args, global) {
    var pos = Kinetic.Type._getXY([].slice.call(args));
    var node = this;

    while (node.nodeType !== 'Stage') {
        pos.x += (global ? 1 : -1) * node.getX();
        pos.y += (global ? 1 : -1) * node.getY();
        node = node.getParent();
    }

    return pos;
};

prototype.toGlobal = function() {
    return this._toCoord(arguments, true);
};

prototype.toLocal = function() {
    return this._toCoord(arguments, false);
};

toGlobal can also be added to Nodes without arguments.

Shortcuts for setListening

Like with setVisible, setListening can also have convenient shortcuts.
For example:
stopListening [-]
cancelListening [-]
supressListening [-]
dontListen [-]
listen [+]

Image proportion sync

Add automatic image proportion sync on resize. Either as an on/off property of Image or as a separate class like I did:

Kinetic.ProportionalImage = function(config) {
    Kinetic.Image.call(this, config);

    this.on('widthChange', this._syncHeight);
    this.on('heightChange', this._syncWidth);

    if (config.width != null) {
        this.setWidth(config.width);
    } else if (config.height != null) {
        this.setHeight(config.height);
    }
};

Kinetic.ProportionalImage.prototype = {
    _syncDim: function(from, to, evt) {
        var img = this.getImage();

        this.attrs[to] = img[to] * evt.newVal / img[from];
    },

    _syncWidth: function(evt) {
        this._syncDim('height', 'width', evt);
    },

    _syncHeight: function(evt) {
        this._syncDim('width', 'height', evt);
    }
};

Kinetic.Global.extend(Kinetic.ProportionalImage, Kinetic.Image);

0 Opacity = hidden

Treat 0 opacity as a hidden Node i.e. don't draw it. Now I have to hide the Node after fading out to save those precious CPU ticks on useless drawing.

Accelerated canvas environment support

As you maybe know currently some companies are making Accelerated canvases for mobile environments (directCanvas and CocoonJS). Those environments don't have all features of HTML and that's why KineticJS does not work out of the box.
I use CocoonJS and for KineticJS to work I've made following changed to Stage:

State.prototype._buildDOM = function() {
    this.content = this.attrs.container;

    this.bufferCanvas = new Kinetic.Canvas();
    this.hitCanvas = new Kinetic.Canvas(0, 0, true);

    this._resizeDOM();
};

State.prototype._getContentPosition = function() {
    var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top : 0, left : 0 };
    return { top: rect.top, left: rect.left };
};

Basically what is needed is to:

  • Check getBoundingClientRect actually exists and if not return 0,0.
  • Add a configuration option to Stage constructor not to make the div wrapper for canvases, but to append them to container directly.
@chrisritter
Copy link

My only concern would be that treating 0 Opacity = hidden could be dangerous/ break existing code. My use case (and a common use case) for opacity 0 is for hit detection / intersection testing.

In your use case: you could override setOpacity to automatically set the node to hidden.

Have you every thought about writing an ActionScript to KineticJS tutorial? -- it'd be an interesting read and maybe help convert more Flash developers to KineticJS

@mihhail-lapushkin
Copy link
Contributor Author

OK, fair enough.

Well, I am not a Flash developer, I've used Flash only once to create a small game for university subject. I needed those functions in my current project, so I implemented them based on my own ideas, but if you want to get some ideas about porting Flash to JS I would recommend EaselJS, since it is a one-to-one port of Flash's object model to Canvas. It also has some cool features like blur filter, but it is still not as good as Kinetic.

@ericdrowell
Copy link
Owner

Wow that's pretty in depth, thanks! My thoughts:

  • isEmpty --> great idea, I'll add something like this, or hasChildren()
  • global to local --> you can use getAbsolutePosition() and setAbsolutePosition()
  • too many shortcuts adds an unnecessary overhead to the library, both in size and maintenance, so I probably won't be adding much of those unless there's a really big demand for them.
  • good idea about an option for keeping an image width and height in proportion, although this could be extended to work with any node using size. I'll add this to my todo list
  • chrisrittter has a good point in regards to the opacity comment, although it may make more sense to use a cloaking method (already on my todo list) which sets a shape visibility to false, but keeps the shape detectable.
  • very interesting about accelerated canvases! I'll add this to my todo list as well

Thanks for all of your suggestions!!

@mihhail-lapushkin
Copy link
Contributor Author

thx for the quick reply!

getAbsolutePosition- did not notice that, thx!

I am using setListening extensively, so I would be really glad to shortcut it, lack of others I can accept =)

@perqa
Copy link

perqa commented Mar 13, 2013

Hello, I am currently trying to use KineticJS in combination with CocoonJS, and as you say, it doesn't work. I tried adding the changes mihhail-lapushkin suggested above, but it still doesn't work. In that code, it says "State.prototype", and yes I have tried that as well as "Stage.prototype", since I assumed it was a typo.

Do you happen to have any more, or updated, information on how to get it working? Grateful for any help or pointers in this.

@mihhail-lapushkin
Copy link
Contributor Author

Hi,

with version 1.3 only this is needed:
Kinetic.Stage.prototype._getContentPosition = function() {
var rect = this.content.getBoundingClientRect ? this.content.getBoundingClientRect() : { top : 0, left : 0 };
return { top: rect.top, left: rect.left };
};

check out my project:
https://github.com/mihhail-lapushkin/Ancient-Riddle

it is a real working game for cocoonjs
maybe you will find something useful there, but I can't remember any other modifications that are I've made to make it work

@perqa
Copy link

perqa commented Mar 13, 2013

Thanks for taking the time to reply! Beautiful game. I have looked at it, but only scratching the surface so far. I tried the code you sent. I run the code snippet when window.onload triggers, so Kinetic should already be loaded. The app works fine in Chrome, but not in the CocoonJS Launcher App on iOS. I am using the latest version 1.3. I attach a screenshot here. You are welcome to email me directly at per <at> quested <dot> net, if you wish, to keep this thread on topic.

KineticCocoonErrors

@mihhail-lapushkin
Copy link
Contributor Author

sorry, did not understand what you meant by "per quested net"

yeah, I've had your problem also when I've used the full version of kineticjs, but for mobile I use a custom build, which excludes lots of the stuff I don't need, so I did not address this issue so much
the problem is coming from drag&drop code line 3079 as the console suggests, so if you are not planning to use drag&drop you can make a custom build without it
if you want to use it you will need to make some kind of a workaround for this issue

@lavrton
Copy link
Contributor

lavrton commented Mar 7, 2014

All suggestions are resolved. I added proportional feature to TODO list. I will close the issue. If need, please, create separate issues for features, bugs.

@lavrton lavrton closed this as completed Mar 7, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants