Ian Obermiller

Part time hacker, full time dad.

Combining pictures into a single photo sheet

Ever wanted to print four photos on a single 4×6 (this is all wallet photos are, after all)? While this sounds like it should be simple, most photo services, like Costco, don’t let you print 2×3 photos unless you order 4 at once, and even then they charge several times the price of a single 4×6. After searching around for solutions, I figured out how to spend a few minutes at the command line using ImageMagick instead.

Step 0: Install ImageMagick

Download and install ImageMagick. On MacOS, it is easiest to use homebrew:

brew install imagemagick

Step 1: Make photos the same size

First, you need to make sure all your photos are the same size, and thus aspect ratio. I’ll assume you want to combine four 2×3 photos into a single 4×6. To resize to a particular aspect ratio:

convert input.jpg -gravity north -crop 2:3 +repage output.jpg

You may want to swap out north for south or center, depending on the image. See the docs on crop and gravity. Note the filenames input.jpg and output.jpg, you should avoid editing your source files.

Now your photos will be the same aspect ratio, but if they are not the same size, you should resize them to the smallest size:

# find the size using "identify"
identify a.jpg

# resize
convert input.jpg -resize 2000x3000 output.jpg

Step 2: Combine and tile

Next, we’ll use the montage command to tile the photos into a single image. Since we are combining into two rows and two columns, the 2×3 aspect ratio will be preserved.

montage a.jpg b.jpg c.jpg d.jpg -geometry +0+0 -tile 2x2 combined.jpg

Note the “-geometry +0+0”, which indicates there should be no horizontal or vertical spacing between them, and that they should be full size. “-tile 2×2” indicates two rows and two columns.

And there you have it! If you have to do this more frequently, I’d recommend a tool with a nice UI, like Photosheet.

Side-by-side diffs for Mercurial (hg) & icdiff revisited

A while back I told you how to get side-by-side diffs in Mercurial using icdiff. Turns out the author of icdiff has added the --recursive flag to make the tool accept directories and diff the contents of the files within. New setup instructions follow.

1. Install icdiff

Same as before: Download and install icdiff, making sure /usr/local/bin is in your $PATH.

2. Setup Mercurial

Next, lets configure Mercurial so that it knows about icdiff. We’ll also set the default pager for all commands to less. Add the following to your ~/.hgrc.

[extensions]
extdiff=
pager=

[extdiff]
cmd.icdiff=icdiff
# extdiff passes two directories to the diff command
# --recursive tells icdiff to treat the two params as directories
# and recursively diff their contents.
# -- line-numbers shows line numbers on both sides
opts.icdiff=--recursive --line-numbers

[pager]
# Setting the variable LESS is like passing those options to less.
# In this case, -F (quit if fits on screen), and -R (pass through control chars,
# required for color output)
pager = LESS='FR' less
# Use pager for these commands only. Add any commands you use here.
attend = icdiff,diff,status,log

You can now replace diff in your Mercurial commands with icdiff, and it will do a side-by-side diff instead of inline.

3. Aliases (optional)

Finally, since hg icdiff is of course too long, add the following aliases to your ~/.bashrc or ~/.zshrc:

# side-by-side diffs for uncommitted files
alias ic='hg icdiff'

# diff all changes since the base revision, including uncommitted
# (from master if you are using bookmarks, for example)
alias ica='hg icdiff -r .^'

# diff the existing changes, excluding uncommitted
alias ice='hg icdiff --ch .'

 

Styling Visited Links with Radium and React

Radium is a library for styling React components that I’ve spent a fair amount of development time on over the past few months. Radium uses inline styles exclusively, and there are some things you just can’t do without CSS. Styling :visited links is one of them. Luckily, Radium provides a <Style> component which makes this pretty easy to accomplish.

The <Style> component will render a <style> tag, and will prepend each selector with the specified scopeSelector. We use the name of the component as the class, but you could be extra careful and append a generated string to the class to be certain it won’t conflict.

import {Component} from 'react';
import Radium, {Style} from 'radium';

@Radium
export default class ListOfLinks extends Component {
  render() {
    return (
      <div className="ListOfLinks">
        <Style
          scopeSelector=".ListOfLinks"
          rules={{
            a: {
              color: 'black'
            },
            'a:visited': {
              color: '#999'
            }
          }}
        />
        <ul>
          <li><a href="http://example1.com">Example 1</a></li>
          <li><a href="http://example2.com">Example 2</a></li>
          <li><a href="http://example3.com">Example 3</a></li>
          <li><a href="http://example4.com">Example 4</a></li>
        </ul>
      </div>
    );
  }
}

You’ll notice I also styled normal links, and that was just for convenience. If I style them inline, like <a href="http://example1.com" style={{color: 'blue'}}>Example 1</a>, I’d have to change the value for visited to #999 !important to make it override the inline style.

Remember, the usual caveats of selectors apply to <Style>, so any children of ListOfLinks that render anchor tags will also be affected. For this reason, you should only use <Style> on components that don’t render {this.props.children}.

Other uses for <Style>:

  • Styling user-generated HTML, like in a CMS
  • Styling the body and html tags (since scopeSelector is optional)

Keyboard Shortcuts with React

In many web apps, you want to trigger an action in response to a keypress when a certain component is showing. I ran into this while playing with NuclearMail. Think gmail style “y to archive” kind of shortcuts. So, building with React, we might have a MessageView component, which, when it is showing, we want to respond to the “y” keypress and archive the message. All we need is the keyboardjs library and some decorator glue code:

// KeyBinder.js

var keyboardjs = require('keyboardjs');

module.exports = function decorateWithKeyBinding(ComposedComponent) {
  var displayName =
    ComposedComponent.displayName ||
    ComposedComponent.name ||
    'Component';

  class KeybinderEnhancer extends ComposedComponent {
    bindKey(keyCombo: string, fn: () => void) {
      this._keyBindings = this._keyBindings || [];
      this._keyBindings.push(keyboardjs.on(keyCombo, e => {
        if (['INPUT', 'TEXTAREA'].indexOf(e.target.tagName) >= 0) {
          return;
        }
        fn();
      }));
    }

    componentWillUnmount() {
      if (super.componentWillUnmount) {
        super.componentWillUnmount();
      }

      if (this._keyBindings) {
        this._keyBindings.forEach(binding => binding.clear());
      }
    }
  }

  KeybinderEnhancer.displayName = `Keybinder(${displayName})`;

  return KeybinderEnhancer;
};

Notice how we ignore bindings fired when an input or textarea has focus is the target, so we don’t trigger “archive” while you are searching for something with the letter “y”.

Then, decorate your component with @KeyBinder and call this.bindKey in componentWillMount:

@KeyBinder
class MessageView extends Component {
  componentWillMount() {
    this.bindKey('y', this._archive);
  }

  _archive = () => { ... };
}

Notice that _archive uses class properties syntax to avoid using bind. You could also make this into a mixin for easier use with createClass style components, or just use the function call syntax instead, MessageView = KeyBinder(MessageView).

Let me know in the comments if you think this would be useful to publish to NPM!

React Pure Render Decorator

If you’ve adopted JavaScript classes when working with React, you may be missing PureRenderMixin. You can emulate it easily using decorators:

var shallowEqual = require('react/lib/shallowEqual');

module.exports = function PureRender(Component) {
  Component.prototype.shouldComponentUpdate = function(nextProps, nextState) {
    return (
      !shallowEqual(this.props, nextProps) ||
      !shallowEqual(this.state, nextState)
    );
  };
  return Component;
};

Use it with the decorator syntax or just as a wrapper around your component:

@PureRender
class Button extends Component { ... }

Button = PureRender(Button);

The logic is exactly the same as PureRenderMixin. Keep in mind that this could break if/when React’s internals are rearranged, since we are deeply requiring shallowEqual. This hasn’t been published to NPM, but if you’d like to see it drop me a comment. Hopefully a pure rendering decorator will make its way into react-pure-render instead.

Shave 45kb off your production webpack + React build

If you’re building a React app for production using webpack, don’t forget this simple plugin for your production build:

new webpack.DefinePlugin({
  'process.env': {NODE_ENV: '"production"'}
})

It will replace all instances of process.env.NODE_ENV with the string "production". When used in conjunction with the uglify plugin, all the code in React that is inside a dev only conditional like if ("production" !== process.env.NODE_ENV) { ... } will be stripped.

On my simple app, this shaved 45kb off the production build before gzip. After gzip saved 13.5kb, still not bad. Win!

Conditionally Load Intl Polyfill with Webpack

So, you want to use the new JavaScript Internationalization API, Intl? Perhaps you even want to use it with the awesome React Intl library. Browser support is okay, but if you want to support <IE11 and any version of Safari you’ll have to use a polyfill. Unfortunately, the polyfill is pretty large if you use the full build with all languages, clocking in at ~150k minified and gzipped. Wouldn’t it be great if we could set up our JavaScript app to download the Intl library only if the browser needs the polyfill? Fortunately, this is really easy to do using webpack.

1. Install intl

npm install --save intl

2. Modify app’s entry point

Before,  our app’s entry point using React was simple and synchronous:


var React = require('react');
var App = require('./App');

React.render(<App />, document.body);

Now, we need to put all our initialization code into a function, and wait to invoke the function until the polyfill is loaded:

function run() {
  var React = require('react');
  var App = require('./App');

  React.render(<App />, document.body);
}

// Check if polyfill required
if (!window.Intl) {
  // Webpack parses the inside of require.ensure at build time to know that intl
  // should be bundled separately. You could get the same effect by passing
  // ['intl'] as the first argument.
  require.ensure([], () => {
    // Ensure only makes sure the module has been downloaded and parsed.
    // Now we actually need to run it to install the polyfill.
    require('intl');

    // Carry on
    run();
  });
} else {
  // Polyfill wasn't needed, carry on
  run();
}

That’s all there is to it. Webpack takes care of splitting the bundle and downloading the polyfill on require.ensure! This method should work with all kinds of polyfills, and keeps your app lean for modern browsers yet working in the rest. For more information, see the webpack documentation for code splitting.

React Anti-Pattern: Positional Children

When designing reusable components with React, you may need to dig into the children prop, say to wrap each child in another element or change the ordering. Once you’ve done so, you may also be tempted to do different things depending on the index of the child. An example from the Facebook codebase is the <LeftRight> component, which floats one child to the left, and another to the right. Its API looks like this:

<LeftRight>
  <div>floated to the left</div>
  <div>floated to the right</div>
</LeftRight>

Instead, simplify the API of <LeftRight> and pass the two children as props instead:

<LeftRight
  left={<div>floated to the left</div>}
  right={<div>floated to the right</div>}
/>

The props-based version:

  • Is easier to implement – no mucking about with React.Children
  • Is easier to use, since the API to the component is now explicit
  • Can have better validation, like requiring the props to be of a certain type
  • Is more flexible – what if left wasn’t required?

This post was inspired by spicyj’s comment on a React issue.

Flux Panel at ReactJS Conf 2015

Last week in Menlo Park was the first ReactJS conference, hosted by Facebook. I had the honor of being on the Flux Panel with some amazing developers. Bill Fisher did an excellent job preparing us for the panel and moderating, and it is chock full of nuggets of wisdom from those of us building some of the largest React+Flux apps. Topics include Relay vs Flux, isomorphic apps, maintainability, and approaches to data fetching. (more…)

Side-by-side diffs for Mercurial (hg)

UPDATE: This is easier now! See my new post, “Side-by-side diffs for Mercurial (hg) & icdiff revisited”.

Ever wish for hg diff in side-by-side view? I find it much easier to scan, assuming you have the horizontal real-estate in your terminal. Here is a simple guide to setting up side-by-side diffs in Mercurial on Linux/OSX: (more…)

Older Posts »