Creating Interesting Paths

Starting from a very simple path, let’s see how easy it can be to turn it into something interesting! The approach below is the basic method I used on my recent fx(hash) release, Crisis Worlds.

Note: The code samples use my own private framework. If you have some basic experience with JavaScript and p5js, it should be easy to adapt them. The variable c represents my personal drawing library, and the methods should translate to p5js almost identically. I also use several random number convenience methods, and what they do should be clear from the function name.

First, we’ll create two starting points, an array to hold them, and then a function to draw them.

image

Below is the output.

image

We need to connect them with a line. We’ll modify the code in the forEach loop to get the next point and draw a line between the current point and the one after it.

image
image

Let’s pull in some code from my last tutorial on generative brushes. But instead of drawing random circles at each step along the line, we’ll use it to build the array of points between the start and end.

image
image

Now we have a perfectly plain line between the start and endpoints. That’s no fun! Let’s add code to move each point around before we add it to the array.

image
image
image

You can go crazy with this, and if you do, you’ll see some interesting behavior soon.

To make things easier from here on, let’s extract the point drawing code into a new function.

image

What if we wanted to further refine and smooth out this line? We need an algorithm to take in all of our rough points and smooth out the corners by adding in new points. The Chaikin Algorithm is the perfect solution for this! Matt DesLauriers has a JavaScript implementation of it that we can use.

Adding the code to our example project and inlining the vec2-copy import, we get this.

image

Then we run it over our points array and get this. The smoothed line is in green.

image
image

Looking nice! What if we want even more smoothing? Just iterate the smoothing function a few times. Let’s modify the chainkinSmooth function to iterate over the input points as many times as we specify.

image

Running this with 3 iterations returns a much smoother line.

image

And that’s it! We’ve gone from a simple line from point A to point B and transformed it into a flowing path. Experiment with different values, even polygons, to see what you can create! The more starting points you have, the wilder the paths will be.

Below are some examples with increasing amounts of starting points (pointsToInsert).

image
image
image

Paths like this are perfect for tracing with a natural media brush 😉. I hope this has given you new ideas and new areas to explore in your work!

Please give me a follow on Twitter @nudoru and Instagram @hfaze! If you use this in a project, give me a shout out, I’d love to see what you make!

Below is the full code for what I’ve created above. As stated above, this is for my own framework and will need to be adapted to p5js.

const chaikinSmooth = (points, itr = 1) => {
    const smoothFn = (input, output = []) => {
        const copy = (out, a) => {
            out[0] = a[0];
            out[1] = a[1];
            return out;
        };

        if (input.length > 0) output.push(copy([0, 0], input[0]));

        for (let i = 0; i < input.length - 1; i++) {
            const p0 = input[i];
            const p1 = input[i + 1];
            const p0x = p0[0];
            const p0y = p0[1];
            const p1x = p1[0];
            const p1y = p1[1];

            const Q = [0.75 * p0x + 0.25 * p1x, 0.75 * p0y + 0.25 * p1y];
            const R = [0.25 * p0x + 0.75 * p1x, 0.25 * p0y + 0.75 * p1y];
            output.push(Q);
            output.push(R);
        }
        if (input.length > 1) output.push(copy([0, 0], input[input.length - 1]));
        return output;
    };

    if (itr === 0) return points;
    const smoothed = smoothFn(points);
    return itr === 1 ? smoothed : chaikinSmooth(smoothed, itr - 1);
};

const drawPoints = (pointsArray, pColor = 'red', lColor = 'blue') => {
    // Loop over the array and pass in the point and the current index
    pointsArray.forEach((point, idx) => {
        c.noStroke();
        c.fill(pColor);
        c.circle(point[0], point[1], 5);

        // Draw a line between the current points, and the next one
        // If it's the last point, don't do anything
        const next = idx < pointsArray.length - 1 ? pointsArray[idx + 1] : null;
        if (next) {
            const px1 = point[0];
            const py1 = point[1];
            const px2 = next[0];
            const py2 = next[1];

            c.stroke(lColor);
            c.line(px1, py1, px2, py2);
        }
    });
};

const draw = () => {
    const cw = c.width; // Width of the canvas
    const ch = c.height; // Height of the canvas
    const m = 200; // Margin

    const x1 = m;
    const x2 = cw - m;
    const y1 = ch / 2 - 50;
    const y2 = ch / 2 + 50;

    const points = [];

    const pointsToInsert = randomWholeBetween(10, 50); // Will insert 1 more than this
    const xIncrement = (x2 - x1) / pointsToInsert;
    const yIncrement = (y2 - y1) / pointsToInsert;

    let currentX = x1;
    let currentY = y1;

    const minOffset = 50;
    const maxOffset = 100;

    for (let i = 0; i <= pointsToInsert; i++) {
        // Only move around the middle points
        if (i > 0 && i < pointsToInsert) {
            // Random radius between the min and max
            const rRadius = randomNumberBetween(minOffset, maxOffset);
            // Random radians between 0 and 2PI, the full circle
            const rRadians = randomNumberBetween(0, Math.PI * 2);
            const offsetX = currentX + rRadius * Math.cos(rRadians);
            const offsetY = currentY + rRadius * Math.sin(rRadians);
            points.push([offsetX, offsetY]);
        } else {
            points.push([currentX, currentY]);
        }

        currentX += xIncrement;
        currentY += yIncrement;
    }

    const smoothPoints = chaikinSmooth(points, 3);

    drawPoints(points, 'red', 'blue');
    drawPoints(smoothPoints, 'green', 'green');

    return false;
};

Generative Brushes Part 1

I make heavy use of ‘brushes’ in most of my generative pieces. I think they’re crucial for adding an extra dimension and a lot of texture to the piece. Below, I’ll create a simple system that you can add and customize on your projects. This technique can be customized and extended to create dry media looks from pencils to charcoal or take a completely new direction!

Note: The code samples use my own private framework. If you have some basic experience with JavaScript and p5js, it should be easy to adapt them. The variable c represents my personal drawing library, and the methods should translate to p5js almost identically. I also use several random number convenience methods, and what they do should be clear from the function name.

Start with two points and a line

The idea is to take two points and draw many little circles between them. It’s the spacing, arrangement, and color of these tiny shapes that determine the look of the final line and what media it looks like. If you have a complex shape, such as a circle, square, etc., then imagine doing this between each pair of points on that shape.

Let’s start with a basic line.

And the code. Here, I define some basic variables, set the context color, and draw the line to the canvas context.

image

The next step is to plot points along the path rather than just drawing a line. We’ll start with a dotted line, drawing a circle at each point as we step between the start and endpoints.

image
image

If you increase the variable stepsBetweenPoints you’ll end up with a more detailed line. The farther apart the start and end points are, the higher you’ll want this value. Here’s what it looks like with 100 steps.

image

Adding interest with randomness and noise

If you’ll notice, the radius of the circles is the thickness of the stroke. By using a random number as the radius, the line becomes much more interesting!

image

This looks like an erratic leaky pen. I’m using this random number utility function to get this value.

image

Let’s make it better with some noise. In this context, it’s helpful to think of noise as a smooth gradation of random values. As we get the 2d noise values of the points on our line, it travels through and noise space and gradually changes. The frequency of the noise will determine how quickly the values change. Simplex noise with a frequency of 0.005 at 1 amplitude is a very smooth place to start.

image
image

Experimenting with this simple approach can yield interesting results! Below, I’ve increased stepsBetweenPoints to 300, changed minRadius to .5, and maxRadius to 5. The result is a wavy ink line.

image

Adding texture

So what about the old-school airbrush look? For that, we need to draw random points around each of the points in our line. For a great explainer of the best way to get a uniform distribution of random points in a circle, watch this excellent video from nubDotDev. These recent tweets from Yazid and Takawo Shunsuke show several methods for point distribution in a circle. Experiment! We’ll the method below for the rest of this article.

image

Using that function to get a uniform random radius, we can pair that with random radians between 0 and two PI to draw random circles around our point, and then we have our old-school spray can.

image

The new function, randomCirclesAroundPoint, creates all of the random circles for us. Thickness is the maximum radius for the points, and density is the number of circles to draw.

image

To visually illustrate what’s going on, here’s a debug view. The green dot is our stepped point, the center of the circle. The red outline is the thickness or the max radius to create the random points.

image
image

Tweaks and ideas

At this point, you have everything needed to create a convincing natural media-drawn line in your projects. You can create a pencil line by tweaking all of the variables we’ve covered so far.

image

One tip, is to use alpha on the circle’s fill color. Below is that line again, but with a fill alpha of 0.25.

image

Below, I’ve increased the alpha to 0.5, and changed the min/max radius of the circles to 0.25 and 1. With circles sizes this small, you’ll need to increase the density quite a bit, but the results are even better.

image

Scaling up the thickness of the line, you can create a charcoal effect.

image

Another trick I’ve used in my work is to snap about 30% of the circles to a multiple of a whole number. This will give the feeling of the media sticking to a paper or canvas grain. Below, 30% of the circles in the randomCirclesAroundPoint function are snapped to an x or y value that’s a multiple of 3.

image

The effect is subtle, but it adds more realistic details. Here’s the updated code with this included.

image

For more complex polygons, like an arc, circle, or square, where the points are close together, the stepsBetweenPoints needs be very low – even 1 in some cases. In my projects, I have all of this wrapped in a function that takes an array of points and the steps, thickness, density, sizes, etc., as options.

Be careful as you start to use this technique in your projects. Drawing too many circles will have a negative performance hit. Experiment with the stepsBetweenPoints and thickness vs density variables. You only need enough to get a convincing look. The closer the points are, the less steps you need between the points. The thinner the line, the less density you need. It’s a good idea to create a function that will lerp these values for you.

I’ve spent a lot of time hunting down performance bottlenecks for it to be a low alpha and very high steps and density. Increasing the alpha let me reduce the other variables and didn’t have a negative impact on the appearance.

A complete function

Below is an example of how this could look in your projects. I’ve taken this code, placed all of the tweaking variables in an object, added checks for different options values, and made it reusable. This is similar to how it looks in my own projects.

Using an object to store and pass the variables makes it easy to change up the looks. You can have one for a pencil, another for charcoal, etc.

const drawLine = (x1, y1, x2, y2, options = {}) => {
    // options defaults, a pencil line
    const {
        stepsBetweenPoints = 10,
        density = 5,
        minThickness = 0.1,
        maxThickness = 2,
        minRadius = 0.25,
        maxRadius = 1,
        noiseFrequency = 0,
        snapPointsPx = 3,
        snapPoinstPct = 0.7,
    } = options;

    const xIncrement = (x2 - x1) / stepsBetweenPoints;
    const yIncrement = (y2 - y1) / stepsBetweenPoints;

    let currentX = x1;
    let currentY = y1;

    // Creates a function that takes x,y as arguments and returns a value from -1 to 1
    // if noiseFrequency === 0 then, it won't be used
    const noiseFn = basicSimplex(noiseFrequency);

    const randomCirclesAroundPoint = (centerX, centerY, thickness, density) => {
        for (let i = 0; i < density; i++) {
            const rndRadius = randomNumberBetweenSq(0, thickness);
            const rndRadians = randomNumberBetween(0, Math.PI * 2);
            let x = centerX + rndRadius * Math.cos(rndRadians);
            let y = centerY + rndRadius * Math.sin(rndRadians);
            const pointRadius = randomNumberBetween(minRadius, maxRadius);

            if (snapPoinstPct && snapPoinstPct < 1) {
                if (randomNumberBetween(0, 1) > snapPoinstPct) x = snapNumber(snapPointsPx, x);
                if (randomNumberBetween(0, 1) > snapPoinstPct) y = snapNumber(snapPointsPx, y);
            }

            c.circle(x, y, pointRadius);
        }
    };

    for (let i = 0; i < stepsBetweenPoints; i++) {
        let rad;
        if (noiseFrequency) {
            rad = (Math.abs(noiseFn(currentX, currentY)) + minThickness) * maxThickness;
        } else {
            rad = randomNumberBetween(minThickness, maxThickness);
        }
        const thickness = rad;
        randomCirclesAroundPoint(currentX, currentY, thickness, density);
        currentX += xIncrement;
        currentY += yIncrement;
    }
};

const draw = () => {
    c.noStroke();

    // slant the lines
    const xOffset = 30;

    // bounds on the color so it's not too dark or light
    const minColor = 50;
    const maxColor = 150;

    // vary the thickness of the lines
    let minOffset = 0;
    let maxOffset = 0;
    const thicknessOffsetStep = 0.05;

    for (let x = 0; x < canvasWidth; x += 15) {
        const r = randomNumberBetween(minColor, maxColor);
        const g = randomNumberBetween(minColor, maxColor);
        const b = randomNumberBetween(minColor, maxColor);
        c.fill(`rgb(${r},${g},${b})`);

        drawLine(x - xOffset, 0, x + xOffset, canvasHeight, {
            stepsBetweenPoints: canvasHeight,
            density: 20,
            noiseFrequency: 0,
            minThickness: 1 + minOffset,
            maxThickness: 3 + maxOffset,
            snapPoinstPct: 0,
        });

        minOffset += thicknessOffsetStep;
        maxOffset += thicknessOffsetStep;
    }
};

I’ll end this article here and continue with simulating paint in a future one. I hope this has given you new ideas and areas to explore in your work!

Please give me a follow on Twitter @nudoru and Instagram @hfaze! If you use this in a project, give me a shout, I’d love to see what you make!

Route change updates with React-router 4

I was updating the packages in my React bootstrap/quick start project yesterday and noticed that a totally rewritten (again) version of React-router was out. Sweet! So let’s upgrade. I’d been updating packages all morning (with the help of Version Eye) so I was ready for an end-of-the-day challenge.

The new API makes much more sense to me than the old way and I really don’t need my container anymore since you can integrate the routing components directly with the app components. “More easier to reason about.” And they’ve added components to handle change animations which I’m going to get into later today.

The one part that wasn’t clear (and wasn’t available via Google or StackOverflow) was how to listen for route changes in a component. With the earlier version (1.something or other) I was using this on my navigation bar to reflect the current route:

import {browserHistory} from 'react-router';

// React stuff 

componentDidMount() {
  browserHistory.listen((event) => {
   this.updateCurrentPath(event.pathname);
  })
}

// More React stuff

I dug into the code to find a solution and discovered this neat pub/sub system they built for it called React-broadcast. You wrap the top level in a broadcaster component and then individual components nested inside are wrapped in a subscriber component to receive updates on a specific channel. Looking at StaticRouter, the parent for the browser and hash routers, the whole route shebang is wrapped in a “location” broadcaster! So you just have to wrap the necessary components in a subscriber and you’ll get updates.

I was able to modify my code above and remove the listener and integrate it directly into my render() method:

import {LocationSubscriber} from 'react-router/Broadcasts';

render() {
  return (
    <div className="navigationbar">
      <LocationSubscriber channel="location">
      {(location) =>(
        <ul>
        {
          this.props.nav.map((item, i) => {
            return <li key={i}><Link
            className={location.pathname === item.route ? 'active' : ''}
            to={item.route}>{item.label}</Link></li>
          })
        }
        </ul>
      )}
      </LocationSubscriber>
    </div>
 );
}

And it works perfectly! The only gotcha is the children of the LocationSubscriber are the result of function rather than nested, but that makes sense since you’re passing the location in.

Hope this helps someone else. Is there a better way to accomplish this? Leave a comment …

I’ve stopped writing my own JavaScript framework because …

This post should have been written back in February! But I’m bad at blogging …

Rolling my own solution was a great way to quickly get up to speed on modern JavaScript syntax and best practices. I think it’s really the best way – for me. But in the end I was never going to be confident in it enough to release or suggest anyone else use it.

I was building more apps and the realization that someone was going to come behind me and maintain these things started to hit home. I’ve been in this situation before, and long term product maintenance and support wasn’t something that I wanted to get into again.

And I was job hunting. “No, I’ve never used React/Angular but I wrote my own thing …” was going to go anywhere. So I quit cold turkey and started picking up React. I’d based a lot of my methodologies on it anyway.

So that’s where I’m at now. As an e-learning developer at Red Hat, I don’t bang out code all day, but React has been great for producing apps very quickly. I’m really happy with it.

I’m writing my own JavaScript framework because …

This is a question that I “know” the answer to, but putting it down has actually been a pretty difficult. However, after discovering Tero Parviainen’s talk “Build You Own AngularJS,” I think I have a pretty good supporting reason.

Going back to my first post on this from April, I did it just to learn the basics of vanilla JS. Looking around too many people are learning frameworks and push code with them while not spending time to grok the core language. I didn’t want to be one of those and this is still true.

I’ve always liked to take things apart and discover what’s under the hood, it’s the best way to see inside of the black box. So that that’s what I’ve been doing – learning JS by looking at the internals (source, tutorials, etc.) of popular frameworks and reimplementing those in my own.

I’m building to learn. I’m building to discover and know how the shit gets done.

I’ve been focusing on React and Redux for the past few months, but I’ve never actually used them, learned how to use them on a real project. I need to get that experience add it to my resume. Not sure what my next project will be but it’ll be built with those tools and when I build it, I’ll know what’s in the box.

My framework is on GitHub.

This is cool …

Haven’t updated this in a REALLY LONG TIME, but progress on my framework is going well. I’ve definitely moved towards React with it and introduced ES6 with the help of Babel / Gulp.

I’m testing out child components and just coded up this little button thing. Really simple, but it’s damned cool to see how little coding it can take on the front end when properly support on the back side with framework architecture.

let counter = 0;

export default Nori.view().createComponent({

  getDOMEvents() {
    return {
      'click button': () => this.setProps({label:'Clicked ' + (++counter) + ' times'})
    };
  },

  template(props, state) {
    return this.from(`
      <div>
        <button>{{label}}</button>
      </div>
    `);
  }

});

 

RxJS based Pub/sub Eventing

An global eventing system is a pretty key piece of a full fledged MVC app. It lets you very easily separate concerns while maintaining communication between discrete parts of the application.

I’ve been using a simple event dispatcher for a while now. At the same time, I’ve had my eye on the excellent, and still way over my head, RxJS library. I had been using it for DOM / browser events, but I couldn’t wrap my head around how to connect event strings (“magic strings”) with an Observable and use that to execute commands or callbacks. Then I discovered this bit of sample code that demonstrated exactly what I wanted to do.

I hand’t looked at the Subject object before, but it does exactly what I need. And the callback / handler / command execute function fit right into the role of the subscribed onNext function.

Adapting the emitter example fit into my framework was straight forward and I ended up with a new Emitter module that replaces both my old EventDispatcher and EventCommandMap.

I’m keeping a simple map of subjects keyed to the event string

_subjectMap[evtStr] = {
 once: once,
 handler: handler,
 subject: new Rx.Subject()
 };

And whenever an event is published, this object is retrieved and the subject’s subscribers are notified. If the event was only supposed to occur once, it’s unmapped safely.

function publish(evtStr, data) {
  var subjObj = _subjectMap[evtStr];

  if(!subjObj) {
    return;
  }

  if(subjObj.once) {
    subjObj.subject.onCompleted();
    subjObj.subject.dispose();
    subjObj = null;
  }
}

Mapping to a command module was painless as well since we just need to map the execute() function to the subject.

function subscribeCommand(evtStr, cmdModule, once) {
  var cmd = require(cmdModule);
  if(cmd.hasOwnProperty('execute')) {
    return subscribe(evtStr, cmd.execute, once);
  } else {
    throw new Error('Emitter cannot map '+evtStr+' to command '+cmdModule+': must have execute()');
  }
}

Adding routes

I had a new JS project come up at work, so I’m taking time to extract my framework from the Gallery project into one that’s reusable for other projects. I should come up with a hipster name for it I suppose. Anyway, I put it on Github as App-Framework.

The Gallery didn’t need to manage multiple views and the URL routes were for  bookmarking to search results. I needed to extend my simple URL router module so that I could bind a controller function to a route change. Since I’d never done this or used a framework that did, this great post gave me a nudge in the right direction.

Setting up a route with the updated router module is pretty simple.

_router.when('/',{templateID:'test', controller:function(obj) {
  console.log('Running route: '+obj.route+', with template: '+obj.templateID);
}});

The when method will map the route (as a key/object property) to a controller function that’s run when the URL changes. Pretty handy.

My app framework utilizes commands for controller functions, so I needed create and addition utility function on my controller to map this to a command:

function mapRouteCommand(route, templateID, command) {
  _router.when(route,{templateID:templateID, controller:function executeRouteCommand(dataObj) {
    command.execute(dataObj);
  }});
}

Mapping is still simple:

mapRouteCommand('/', 'defaultView', _self.RouteInitialViewCommand);
mapRouteCommand('/1', 'test1', _self.RouteOneViewCommand);

From this point, it will call a method in the AppView to load/render/show the view.

Better Modules: Hacking my way towards modularity

“A beginning programmer writes her programs like an ant builds her hill, one piece at a time, without thought for the bigger structure. Her programs will be like loose sand. They may stand for a while, but growing too big they fall apart.

Realizing this problem, the programmer will start to spend a lot of time thinking about structure. Her programs will be rigidly structured, like rock sculptures. They are solid, but when they must change, violence must be done to them.

The master programmer knows when to apply structure and when to leave things in their simple form. Her programs are like clay, solid yet malleable.”

Master Yuan-Ma, The Book of Programming

 

After implementing the automatic namespace import thing the other day, I wasn’t happy that I needed something this like this in the first place. Locking everything behind a rigid namespace was prohibiting reusability. I trying to move forward, but my structure was getting in the way. I’m at the middle paragraph in the quote above.

I wanted to move towards something akin to AMD or CommonJS modules, but I didn’t want to add the additional complexity of a packaging system (Browserify, Webpack, etc.) to my build process (*Why? See below …). I also wanted to know more about how they worked once all of the files are packed in a big file at the end of the process.

The Modules chapter of the Eloquent JavaScript book was a perfect place to start with this. It breaks down the logic and creation of both CommonJS and AMD modules as well as providing basic require() and define() functions. Cujujs.com provides a more insight to how CommonJS modules work in practice also.

Ben Clinkinbeard wrote a great post explaining what the other end of Browserify looks like – how it packages all of the external files together in to one big IIFE and then pulls them out again.

With that, I wrote my own little module system – trying to follow what I was learning about CommonJS. I don’t want to lazy load all of the files so I chose to use a module ID. I’m still using my namespaces for this – it helps to keep them organized in a logical way. At least in my head.

A module skeleton

define('package.moduleID',
  function(require, module, exports){
    exports.myMethod = function() {};
  });

All of the code for the modules is wrapped in a function. I’m passing in the global require function and the module and exports objects. The require() function handles that (below).

The define() function was borrowed from AMD, but it’s much simpler. It stores the modules function code in an object under the ID:

function define(id, moduleCode) {
  if(id in define.cache) {
    return;
  }
  define.cache[id] = moduleCode;
}
define.cache = Object.create(null);

“Loading” a module is straight forward:

var _DOMUtils = require('nudoru.utils.DOMUtils');

The require() function looks up the ID from the define.cache, creates the exports and module objects and invokes the code. It’s also cached for performance later. The returned module is a singleton, having been cached for later use after it’s first instantiated.

function require(id) {
  if (id in require.cache) {
    return require.cache[id];
  }

  var moduleCode = define.cache[id],
      exports = {},
      module = {exports: exports};

  if(!moduleCode) {
    throw new Error('Require: module not found: "'+id+'"');
  }

  moduleCode.call(moduleCode, require, module, exports);
  require.cache[id] = module.exports;
  return module.exports;
}
require.cache = Object.create(null);

I created requireCopy() function that returns an uncached instance of the module. I’m using it for my menus when I need several unique instances of a module – one for each item.

I’m spent a few hours today refactoring my utility classes all of my components with this pattern. It’s testing out well and the resulting code is a lot cleaner. At this point, I’m not quite sure if I’m going to refactor the actual application code … But maybe I’ll feel differently on Monday.

Many thanks to Dustan Kasten for guidance on all of these module systems!

Why am I avoiding packaging?

I’m trying to keep the concat’d JavaScript file as human editable as possible. I want other people to be able to edit my code without needing to install a suite of build tools – something likely to be difficult for most people where I work.

A Tangent

While trying to figure out a problem I did something interesting in the requireCopy() function. Instead of just pulling the instance from the define cache, I created a whole new copy it with some string manipulation. I was interesting in that it did work fine, but it didn’t solve my problem so I removed it.

var funcBody = srcFunc.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1],
newFuncCode = new Function('require, module, exports', funcBody);

Manipulating the function body as plain text has some interesting possibilities. It might be possible to regex the var = require() statements and make a map or perform some light dependency injection.

 

Namespacing Javascript Code for Great Good

Edit This didn’t last long! A day after posting this, I moved to a better, clearer, more modular pattern.

 

I kept my code nice and tidy while developing my app by using proper namespacing to keep it all organized under sane objects. For objects that I want to be global, I’m borrowing from Objective-C and using prefixes, so NObjThingy.

As I’m going back and fixing broken windows, I’ve taken my utility classes out of the global space and put them behind a nudoru.util.* which is great and all, but now using them is ugly

nudoru.util.ObjectUtils.method('foo');

Back in AS3 land, there was true importing of other classes. Once imported, you could access their methods cleanly. I wanted something like that.

I wrote a simple function that basically does that.

function NImport(context, libArry) {
  libArry.forEach(function(lib) {
    var parts = lib.split('.'),
      obj = parts[parts.length-1];
    context[obj] = eval(lib);
  });
}

Usage is simple

NImport(this, ['nudoru.utils.NLorem']);

Accessing also

console.log('lorem: '+this.NLorem.getText(3,5));

This approach has speed advantages since we they’re local variables and we don’t have to look them up. The usage of eval() is dirty, but it works out really well in this case.

Any thoughts on this approach? It’s solving an immediate problem for me, but has anyone else done this differently?