Grade Between Two Hex Colors

CSS colors gradation example

Yesterday I wanted to gradually shade between two hex colors. To perform artihmetic/math on hex colors in PHP you need to break them apart, turn them into decimals, change them back into hex and then put them back together.

Here’s what I came up with:

function hexColorToRgb($color) {
    return [hexdec(mb_substr($color, 0, 2)),
        hexdec(mb_substr($color, 2, 2)),
        hexdec(mb_substr($color, 4, 2))];
}

function colorGrade($p, $start, $end) {
    $start_rgb = hexColorToRgb($start);
    $end_rgb = hexColorToRgb($end);
    $rgb = [$start_rgb[0] * (1.0 - $p) + $end_rgb[0] * $p,
            $start_rgb[1] * (1.0 - $p) + $end_rgb[1] * $p,
            $start_rgb[2] * (1.0 - $p) + $end_rgb[2] * $p];
    return dechex($rgb[0]) . dechex($rgb[1]) . dechex($rgb[2]);
}

// Example:
$start_color = 'c4dbf5';
$end_color = '333333';
echo colorGrade(0.25, $start_color, $end_color); # 9fb1c4
echo colorGrade(0.5, $start_color, $end_color);  # 7b8794
echo colorGrade(0.75, $start_color, $end_color); # 575d63

PHP Lint in Makefile

I ran into a little problem adding php -l to a Makefile. PHP lint is a little verbose outputting “No syntax errors detected” for every file that has no problems. I don’t really want that output but getting rid of it with grep -v means that make treats no errors (grep didn’t find any lines to show) as a failure and errors (grep found some lines to show) as a success. make then terminates in the success case and continues or exits with success in the failure case!

lint:
	@! find . -name "*.php" | grep -v "^./vendor" | xargs -I{} php -l '{}' | grep -v "No syntax errors detected"

The trick is to negate the exit code of the entire pipeline like so:

lint:
	@! find . -name "*.php" | grep -v "^./vendor" | xargs -I{} php -l '{}' | grep -v "No syntax errors detected"

A Penguin Book in CSS

I was reading about Gill Sans and I looked at the sweet Penguin cover in that article and I wondered if I could do the same in CSS.

Here’s my attempt:

You can see it on it’s own page at bluebones.net/penguin.

Mustache Templates in PHP

I’ve always admired the simplicity of Mustache templates but the complication of internationalization support has always prevented me using them until a recent project. I used them in my Magic: the Gathering tournament software.

Mustache templates look like this:

<h2>Create Event</h2>

<form action="{{formAction}}" method="post">
  <label for="format">Format</label> <input type="text" name="format">
  <label for="cost">Cost</label> <input type="text" name="cost">
  <input class="btn btn-primary btn-block" type="submit">
</form>

You can see a bunch from the project at https://github.com/bakert/tournament/tree/master/views.

As long as you have { "require": { "mustache/mustache": "~2.5" } } in your composer.json using them is as simple as:

$loader = new Mustache_Loader_FilesystemLoader('path/to/templates');
$engine = new Mustache_Engine(['loader' => $loader]);
echo $engine->render('template_name', $arguments);

I wrapped this up in a class (Template) and a global (T()) so I could make calls like this:

echo T()->signin($args);

CSS Sprite for Magic: the Gathering Mana Symbols

Image:

Mana symbols sprite

CSS:

.mana {
    display: inline-block;
    background: url('/img/mana/mana.png') no-repeat;
    color: transparent;
    width: 15px;
    height: 15px;
}

.mana-2b { background-position: -0px -0px }
.mana-br { background-position: -15px -0px }
.mana-r { background-position: -30px -0px }
.mana-gw { background-position: -45px -0px }
.mana-2r { background-position: -60px -0px }
.mana-2w { background-position: -75px -0px }
.mana-rb { background-position: -90px -0px }
.mana-rg { background-position: -0px -15px }
.mana-wb { background-position: -15px -15px }
.mana-6 { background-position: -30px -15px }
.mana-gr { background-position: -45px -15px }
.mana-bu { background-position: -60px -15px }
.mana-s { background-position: -75px -15px }
.mana-2 { background-position: -90px -15px }
.mana-8 { background-position: -0px -30px }
.mana-wu { background-position: -15px -30px }
.mana-ru { background-position: -30px -30px }
.mana-cp { background-position: -45px -30px }
.mana-uw { background-position: -60px -30px }
.mana-3 { background-position: -75px -30px }
.mana-gb { background-position: -90px -30px }
.mana-2g { background-position: -0px -45px }
.mana-5 { background-position: -15px -45px }
.mana-16 { background-position: -30px -45px }
.mana-bp { background-position: -45px -45px }
.mana-y { background-position: -60px -45px }
.mana-17 { background-position: -75px -45px }
.mana-11 { background-position: -90px -45px }
.mana-2u { background-position: -0px -60px }
.mana-ug { background-position: -15px -60px }
.mana-wg { background-position: -30px -60px }
.mana-b { background-position: -45px -60px }
.mana-up { background-position: -60px -60px }
.mana-gu { background-position: -75px -60px }
.mana-ub { background-position: -90px -60px }
.mana-u { background-position: -0px -75px }
.mana-rp { background-position: -15px -75px }
.mana-19 { background-position: -30px -75px }
.mana-13 { background-position: -45px -75px }
.mana-g { background-position: -60px -75px }
.mana-12 { background-position: -75px -75px }
.mana-wr { background-position: -90px -75px }
.mana-w { background-position: -0px -90px }
.mana-gp { background-position: -15px -90px }
.mana-bw { background-position: -30px -90px }
.mana-bg { background-position: -45px -90px }
.mana-ur { background-position: -60px -90px }
.mana-7 { background-position: -75px -90px }
.mana-x { background-position: -90px -90px }
.mana-rw { background-position: -0px -105px }
.mana-9 { background-position: -15px -105px }
.mana-10 { background-position: -30px -105px }
.mana-20 { background-position: -45px -105px }
.mana-14 { background-position: -60px -105px }
.mana-0 { background-position: -75px -105px }
.mana-wp { background-position: -90px -105px }
.mana-18 { background-position: -0px -120px }
.mana-1 { background-position: -15px -120px }
.mana-15 { background-position: -30px -120px }
.mana-4 { background-position: -45px -120px }

Usage:

    <span class="mana mana-2">2</span>
    <span class="mana mana-b">B</span>