0

Problem

I'm writing a javascript library for skeletal animations on canvas, and I want to be able to encapsulate entities as JSON data. For example, if I want to draw a minotaur, I simply fetch minotaur.json and it contains information about sprite sheets, bone angles, animations, etc. My problem is that I want library users to be able to hook into my "draw" function so that user functions can be called while the object is drawn (kind of like a primitive shader). For example, directional lighting or a red enraged effect can be implemented on individual sprites using such a hook. However, I want these hooks to be able to be encapsulated in my JSON object as well. The only way that I can think of to accomplish this is storing the functions as strings and then calling eval on them.

Question

Obviously, eval is evil, and I've never actually used it in code. Afaik there is no way to encapsulate a function in JSON. Is this actually a situation where eval is acceptable? Or is wanting to store these entities as JSON data a fool's errand?

Josh
  • 338
  • 2
  • 13
  • my first thought is: why not stores geometry as JSON and functions (e.g. shaders) as JavaScript files? – mb21 Mar 15 '16 at 21:00
  • All together now: *"eval is evil"*, *"eval is evil"*. Don't try to understand `eval`, just follow the mantra blindly. FWIW: Since JSON is about storing data I would not recommend to store code in there. It's not really maintainable. But that has nothing to do with `eval`. – Felix Kling Mar 15 '16 at 21:02
  • @mb21 That's definitely a possible solution. Dunno why I didn't think of it haha – Josh Mar 15 '16 at 21:12
  • @FelixKling You're right about it not being maintainable, but my animation editor plops out JSON so if the user wants to edit such a function, they wouldn't have to dig around the JSON themselves. – Josh Mar 15 '16 at 21:14
  • eval is not "evil" if you can ensure that the data is trusted. We do this all the time via secure protocols. You may also want to do a validation pass on the code invalidating anything that uses more than the required,eg Any DOM access is invalid, and only access locally scoped variables. You could also consider sandboxing the code in a worker or separate domain and rather than eval you can use the function constructor. `var shader = new Function( [arg1 [, arg2 [, ...argN] ], ] code)` JSON is for transport/serialization/storage and is as good a place as any for code. Don't follow mantras! – Blindman67 Mar 16 '16 at 05:08

1 Answers1

1

Instead of eval, you could use Function:

var hook = new Function(codeStr);

// Executing
hook();
nasso
  • 603
  • 5
  • 13