0

I've got a problem using the apply() method from Function.prototype.apply().

I'm trying to create a series of drawings on my CreateJS stage by passing arrays of arguments to the bezierCurveTo method using apply(). This will allow me to loop through about a hundred such sets of arguments and draw a full picture.

However, apply() isn't working on the bezierCurveTo method (it works on moveTo and lineTo).

Instead, I get

TypeError: this.append is not a function

Does anyone have any ideas about why this might be happening? I'm not clear on why it works on the other methods and not bezierCurveTo.

var myData = {
  curveTo: [214.1, 853.1, 327.1, 903.7, 451.8, 903.7],
};

var sha = new createjs.Shape();
sha.graphics.bezierCurveTo.apply(myData.curveTo);

Thank you.

Edit:

Stack trace shows this is where the error lies:

p.moveTo = function(x, y) {
    return this.append(new G.MoveTo(x,y), true);
};
Alex Fink
  • 43
  • 1
  • 6

2 Answers2

1

The first argument to .apply is the context, ie. the value of this in the callback.

I think the correct call is:

sha.graphics.bezierCurveTo.apply(sha.graphics /* or maybe sha? */, myData.curveTo);

This is equivalent to:

sha.graphic.berzierCurveTo(214.1, 853.1, 327.1, 903.7, 451.8, 903.7);

More on .apply:

var obj = {
    "foo": "bar"
};
function get_foo() {
    return this.foo;
}
get_foo.apply(obj, []); // "bar" first argument becomes `this` in callback
get_foo.bind(obj)(); // "bar" .bind() returns a copy of the function with bound context
Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • Thanks for your response. This still gives the same error, whether using "sha" or "sha.graphics". I've also tried "this", but that didn't work either. – Alex Fink May 04 '15 at 14:11
  • Can you give a full stacktrace of the error? This is what you're using, correct? https://github.com/CreateJS/EaselJS/tree/master/src/easeljs/display – Halcyon May 04 '15 at 14:14
  • I take it back, everywhere I try to use .apply() in this way (so .lineTo() .moveTo()) also fails with the same error. How do I give a full stack trace Halycon? – Alex Fink May 04 '15 at 16:14
  • Open the console and click on the error: http://s4.postimg.org/y05dw77x9/Untitled.png this in Chrome, Firefox has something similar. – Halcyon May 04 '15 at 16:19
  • Ah, I didn't do that because it just had the entire minified EaselJS without a pointer to exactly what was going wrong. Should I be doing something different (thanks again for all your help) – Alex Fink May 04 '15 at 16:27
  • For debugging get the non minified version, that might help you understand where the problem is. – Halcyon May 04 '15 at 20:45
  • Thank you! Here's the place it details there error (this on the .moveTo(), but same error as bezierCurveTo()): p.moveTo = function(x, y) { return this.append(new G.MoveTo(x,y), true); }; – Alex Fink May 04 '15 at 21:32
  • I think this has helped me track down the reason - .apply() can't be used directly with the new operator, as this tries to do. See answer here: http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible – Alex Fink May 04 '15 at 22:32
0

So, I found an answer to this problem and wanted to follow up. Mad props to Halcyon for their patient guidance as I worked through this problem. The issue seems to be a combo of the way the library CreateJS maps these functions on to standard Javascript canvas methods. Because it is creating new objects, the apply operator won't work in this instance.

Read more here: Use of .apply() with 'new' operator. Is this possible?

Long story short, when using "new" operator, .apply() won't work as a way to expand an array as a series of arguments on a function call, no matter how you try to set the context.

Community
  • 1
  • 1
Alex Fink
  • 43
  • 1
  • 6