MartinSStewart / elm-box-packing / Pack

Efficiently pack 2D boxes together.

Note that this package uses Quantity instead of raw Ints and Floats. You'll need to install ianmackenzie/elm-units to get started.

Generic packing

Functions for packing boxes together. Scroll down to the Image Packing section if you want to work specifically with images.

pack : Config number units -> List (Box number units a) -> PackedBoxes number units a

Pack generic boxes together.

defaultConfig : Config number units

Default configuration for packing boxes. Zero spacing and no growing the container width and height to a power of two.


type alias Box number units a =
{ width : Quantity number units
, height : Quantity number units
, data : a 
}

A box we want to pack and its accompanying data. Use this with pack.


type alias Config number units =
{ spacing : Quantity number units
, powerOfTwoSize : Basics.Bool 
}


type alias PackedBoxes number units a =
{ width : Quantity number units
, height : Quantity number units
, boxes : List (PackedBox number units a) 
}

All of the boxes we've packed together and how large the containing region is.


type alias PackedBox number units a =
{ x : Quantity number units
, y : Quantity number units
, width : Quantity number units
, height : Quantity number units
, data : a 
}

A box, now packed into a larger rectangle. The width and height of these boxes will be positive even if the corresponding Box had a negative width or height.

Image packing

Suppose you have a lot of images and you want to load them in as a single image to reduce HTTP requests or simplify texture management in WebGL. With these functions you can generate a texture atlas (also called a sprite sheet) to pack all the images together.

textureAtlas : Config Basics.Int Pixels -> List (ImageBox a) -> TextureAtlas a

Pack images together to create a single texture atlas image.

Note that this is a slow process. Even for a small texture atlas (256x256 pixels) it can take a couple seconds and for large images it's probably not a good idea to try. If you need something fast then it's probably a better idea to just use pack and then draw the texture atlas using an HTML5 canvas or something.


type alias ImageBox a =
{ image : Image, data : a }

An image we want to pack and its accompanying data. Use this with textureAtlas.


type alias TextureAtlas a =
{ packedBoxes : PackedBoxes Basics.Int Pixels a
, atlas : Image 
}

A texture atlas image and accompanying data. Note that Image may contain functions. Don't store this data structure in you model. Instead convert Image into a string or bytes and store that.

Serialization

If you want to save your packed boxes/images and then later load them into your app, these functions (when used with elm-serialize) should help.

textureAtlasCodec : Serialize.Codec e a -> Serialize.Codec (TextureAtlasCodecError e) (TextureAtlas a)

A codec for TextureAtlas.


type TextureAtlasCodecError e
    = FailedToParseImage
    | PackedBoxDataError e

These are possible errors we can get when decoding with textureAtlasCodec.

packedBoxesCodec : Serialize.Codec e a -> Serialize.Codec e (PackedBoxes Basics.Int units a)

A codec for PackedBoxes when dealing with integer values.

packedBoxesCodecFloat : Serialize.Codec e a -> Serialize.Codec e (PackedBoxes Basics.Float units a)

A codec for PackedBoxes when dealing with floating point values.