MandalaTV
Personal and Professional Blog of Rich Hauck

Eastern State Penitentiary

by: Rich Hauck

On a recent trip to Philadelphia (primarily to hear UX expert Jared Spool speak at Wharton) I just so happened to drive by Eastern State Penitentiary. I was first introduced to this landmark by the work of several of my photography students, and the allure of its decaying state forced a spot on my bucket list ever since.

I traveled to Alcatraz several years back, but besides the beautiful San Francisco Bay backdrop, I’m sorry to say it didn’t really hold a candle to the decadence on display here.

Many of the images birthed from peoples’ cameras are the same symmetrical, cliched pinups (including mine, below), but it remains a photographer’s playground. It was definitely worth the visit, if only to hear Steve Buscemi’s voice guide me around.

_12A0208

_12A0233

_12A0236

_12A0211

_12A0202


Categories:photography
Comments: 0

Integrating gulp-file-include into Yeoman’s generator-gulp-webapp

by: Rich Hauck

Using include files in my HTML templates has become an essential part of my web design workflow, and I’ve been using gulp-file-include in conjunction with generator-gulp-webapp. While gulp-webapp includes a gulpfile.babel.js file, it needs a few modifications to get HTML include files to display both when serving and when building.

I came across a helpful thread here on GitHub, though as I stated in the comments, I couldn’t get includes to display when building. Below is the complete solution. Basically,

  1. I create a fileinclude task (L44)
  2. I modify the html task to include a fileInclude() call (L57)
  3. I include fileinclude in the serve task (L95)
  4. I check for include file changes within the watch task (L114)

Here’s the full file:

// generated on 2016-01-02 using generator-gulp-webapp 1.0.4
import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import browserSync from 'browser-sync';
import del from 'del';
import {stream as wiredep} from 'wiredep';

const $ = gulpLoadPlugins();
const reload = browserSync.reload;

gulp.task('styles', () => {
  return gulp.src('app/styles/*.scss')
    .pipe($.plumber())
    .pipe($.sourcemaps.init())
    .pipe($.sass.sync({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['.']
    }).on('error', $.sass.logError))
    .pipe($.autoprefixer({browsers: ['> 1%', 'last 2 versions', 'Firefox ESR']}))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'))
    .pipe(reload({stream: true}));
});

function lint(files, options) {
  return () => {
    return gulp.src(files)
      .pipe(reload({stream: true, once: true}))
      .pipe($.eslint(options))
      .pipe($.eslint.format())
      .pipe($.if(!browserSync.active, $.eslint.failAfterError()));
  };
}
const testLintOptions = {
  env: {
    mocha: true
  }
};

gulp.task('lint', lint('app/scripts/**/*.js'));
gulp.task('lint:test', lint('test/spec/**/*.js', testLintOptions));

gulp.task('fileinclude', () => {
  return gulp.src('app/*.html')
    .pipe($.fileInclude({ prefix: '@@', basepath: '@file' }))
    .pipe(gulp.dest('.tmp'))
    .pipe(reload({stream: true}));
});

gulp.task('html', ['styles'], () => {
  return gulp.src('app/*.html')
    .pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.cssnano()))
    //.pipe($.if('*.html', $.htmlmin()))
    .pipe($.if('*.html', $.fileInclude({prefix: '@@', basepath: '@file'})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', () => {
  return gulp.src('app/images/**/*')
    .pipe($.if($.if.isFile, $.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    }))
    .on('error', function (err) {
      console.log(err);
      this.end();
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', () => {
  return gulp.src(require('main-bower-files')('**/*.{eot,svg,ttf,woff,woff2}', function (err) {})
    .concat('app/fonts/**/*'))
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', () => {
  return gulp.src([
    'app/*.*',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', del.bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['fileinclude', 'styles', 'fonts'], () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch([
    'app/*.html',
    'app/scripts/**/*.js',
    'app/images/**/*',
    '.tmp/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/**/*.html', ['fileinclude']);
  gulp.watch('app/styles/**/*.scss', ['styles']);
  gulp.watch('app/fonts/**/*', ['fonts']);
  gulp.watch('bower.json', ['wiredep', 'fonts']);
});

gulp.task('serve:dist', () => {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['dist']
    }
  });
});

gulp.task('serve:test', () => {
  browserSync({
    notify: false,
    port: 9000,
    ui: false,
    server: {
      baseDir: 'test',
      routes: {
        '/scripts': 'app/scripts',
        '/bower_components': 'bower_components'
      }
    }
  });

  gulp.watch('test/spec/**/*.js').on('change', reload);
  gulp.watch('test/spec/**/*.js', ['lint:test']);
});

// inject bower components
gulp.task('wiredep', () => {
  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['lint', 'html', 'images', 'fonts', 'extras'], () => {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], () => {
  gulp.start('build');
});



Categories:webdesign
Comments: 1

My 2015 in Pictures

by: Rich Hauck

2015 brought an unbalanced work load and a lot of home upgrades. There wasn’t necessarily anything wrong with last year, but I won’t deny that I’m looking forward to this upcoming year.


Categories:webdesign
Comments: 0

Christmas Card 2016

by: Rich Hauck

This year, I enlisted the help of two younger artists.

xmas2015card

xmas2015card-inner

IMG_1911

I’m not sure anyone got my Joan Miró reference…

It’s still fun to hear about people’s anticipation for these cards and how some folks collect them. If you know me and want on next year’s list give me a holler.

IMG_1950


Categories:christmas-card
Comments: 0

The TorchBearer Labels That No One Will Ever See

by: Rich Hauck

Okay, so it’s a misleading title (especially now with this post), but it sounds cool.

Before I apparently became famous as the guy in this photo, my former claim to fame was as the “TorchBearer label guy.” I’m (finally) revisiting my past identity by working on the Psycho Curry label, and I figured I’d share a set of  labels that were seen exclusively by the trade show circuit.

The good folks at Datum Storage Solutions are fans of both TorchBearer’s sauces and their labels, and they commissioned me to do two custom labels for mini-bottles for trade shows. The theme: spartans and zombies.

In what’s become a rarity in my workflow, I actually did some starting sketches on paper before moving to digital. Here’s some of the sketches along with the final product.

spartan-2

spartan-1

 

spartan

zombie


Categories:art Illustration
Comments: 0

Harrisburg’s Greenbelt in Infrared

by: Rich Hauck

 

I recently squeezed in a bike ride around the Greenbelt before the autumn’s breeze proved unbearable. I lugged along my SLR and my tripod, and while my tripod bag didn’t survive the trip, I made it out with these infrared photos.

MG_3662

I’ve always found the state hospital grounds to be some of the most tranquil parts of the ‘burg.

MG_3655

 

MG_3688

With a daylight white balance the shots come out very red (below). Personally, I find these far more interesting than converting to B&W, although I realize it’s not for everyone.

MG_3655

I once compared a color-to-black-and-white conversion against an infrared one and was able to generate pretty similar results. Trying to emulate an infrared image in Photoshop would be much more difficult, if not impossible.

 

MG_3694

 

 

I was really surprised to not be able to find an equivalent of the Channel Mixer in Adobe Photoshop’s RAW window. Tweaking the red channel yields some pretty wild results.

_MG_3670


Categories:Harrisburg photography
Tags:infrared
Comments: 0

Revisiting Vermont

by: Rich Hauck

Well, I didn’t manage to do too much traveling this summer, but I did make another trek up to Vermont as part of a beer run/bachelor party. Somehow, no matter how late I stayed up, my body had an internal alarm clock that woke me up around 6 a.m. Fortunately, I made the most of it by taking some beautiful shots of the countryside.

_MG_3610
_MG_3602_MG_3532 _MG_3543

The sunsets weren’t too shabby, either.

_MG_3549 _MG_3558 _MG_3595   IMG_1339

I did say beer, didn’t I? Part of the trip involved visiting Hill Farmstead.

IMG_1356

The ordering process has vastly improved in the course of a year. This time, I wasn’t stuck in a 3-hour line (at least on the Saturday morning when I visited). Instead, I was issued a numbered order card upon entering the brewery. The number assured my place in the queue, and they allow you to visit the tap house (for up to two pints) as you wait.

IMG_1340

I was really surprised that the tap house remained unfinished, as a wooden skeleton was already standing a year before. I can’t fault the brewery, as they’ve clearly been busy with production.

IMG_1348

Lastly, here’s a lovely picture of our group (along with items all found in the barn we rented):

IMG_3618


Categories:travel
Tags:vermont
Comments: 0

Modifying Yeoman gulp-webapp to use Browserify and React JS

by: Rich Hauck

yeoman

I’ve become a big fan of Yeoman’s gulp-webapp generator and have found myself integrating it into my regular development workflow since it handles code testing, text minification, live reloading, and image optimization.

In an effort to integrate Facebook’s React JS library I found several third-party generators, but wasn’t satisfied with any of them. Many stray from the vanilla gulp-webapp, whether it’s switching from SASS to LESS, eliminating Bower, or relying upon Grunt JS instead of Gulp.

One of the closest solutions I uncovered was a React Recipe that ships with the gulp-webapp repository. These step-by-step instructions worked fine, though it relies on your React classes being included in order of dependency. So, if you don’t place the <script> tags representing your classes in the right order within your index.html, your app will fail.

I felt that calling require() at the top of my Javascript class files to pull only the necessary dependencies was a more elegant solution. Call it nostalgia, but this is cleaner code harks back to my days of tinkering with Java and ActionScript. This approach requires Webpack or Browserify, of which I chose the latter. I should mention I came across this blog post that accomplished what I wanted to do, but it’s for a much earlier version of gulp-webapp and doesn’t work with the current version.

So here’s what I came up with:

1. Install the standard gulp-webapp by calling yo gulp-webapp in your command line.

  1. Install React via Bower: bower install --save react 
  2. Include the newly-downloaded React as a dependency in app/index.html (<script src="/bower_components/react/react.js"></script>)
  3. Install NPM dependencies: sudo npm install --save-dev browserify reactify vinyl-source-stream 
  4. Change gulpfile.js to include custom scripts() task. Task scripts() is called in serve() and html(). Task watch() has been modified to watch /.tmp and /scripts for changes. Here’s the scripts task:gulp.task('scripts', function() {
    return browserify({
    //paths: ['./app/scripts/'],
    entries: ['./app/scripts/App.js'],
    transform: ['reactify'],
    debug: true
    })
    .bundle()
    .pipe(source('main.js'))
    .pipe(gulp.dest('.tmp/scripts/'));
    });

    Basically, this task looks at App.js, converts it and all dependencies from JSX to regular JavaScript, then outputs all of the code into /tmp/scripts/main.js.

    When publishing via gulp build, it will JSHint the compiled JavaScript before copying it from /tmp into the /dist folder.

  5. Add javascript class files to /scripts directory. Delete main.js (as the gulpfile’s scripts() task will generate a main.js file). I chose *.js extensions only so that my text editor (Sublime Text 3 and Atom) would recognize the files and color the syntax.
  6. Add <div id="app"></div> to index.html, as this is where the app is being told to render itself in /app/scripts/App.js.

 

The whole thing is available on GitHub. I hope it helps someone else out. Feel free to drop me a line if there’s something that can be improved.

 


Categories:CSS javascript webdesign
Comments: 0

BarCampHbg is back. And that’s a good thing.

by: Rich Hauck

BarCampHbg7

This is a follow-up to my previous post, “The Fate of Barcamp Harrisburg“.

Well, while I was relatively comfortable coming to terms with barcamp ending, many of you were not, and that’s a good thing. I received a lot of supportive feedback, and as a result, Barcamp Harrisburg will go on for its seventh consecutive year with a new date and a new host for 2015.

Working with the great folks at The Tech Council of Central PA, BarCampHbg will help serve as a kickoff event for the week-long UPNEXTFEST. Formerly Harrisburg Startup Weekend, UPNEXTFEST helps to nurture the local and potential startup community.

This year’s camp is scheduled for Saturday, October 10, 2015 at ITT Technical Institute Harrisburg. It’s only a little ways from downtown, and along with the venue change comes relief from paid parking(!).

More info will be coming soon and posted to the BarCampHbg website. In the meanwhile, save the date. If you’re interested in sponsoring, please drop a line to info@barcamphbg.org. Hope to see you there!

 


Categories:Harrisburg javascript mobile webdesign
Comments: 6

About Rich Hauck

Rich Hauck

I'm a creative technologist at Hauck Interactive, Inc. and an adjunct instructor at HACC. I live in Harrisburg, Pa. with my wife and two boys. I enjoy good coffee, Trappist beers, Orioles baseball, and good design.