30. September 2015

Copy To Clipboard JavaScript Only

Just the other day Clipboard.js as released and I got super excited about not using Flash anymore to copy thing.

I looked through their code and they're just using Document.execCommand() to copy to clipboard. I figured I would play with it and did it myself in just a few lines of code. Here's the Pen of my work:

 

See the Pen Copy To Clipboard JS Only by Josh Fabean (@fabean) on CodePen.

 

The main magic of this is right on this one line of JavaScript:

document.execCommand('copy', false, document.getElementById('select-this').select());

I grab the input, select() it then run document.execCommand on it. Super easy, and fun to do. If you want to use this yourself you should probably use the full library as it has nice fallbacks and works in more cases anyways.

It ended up getting picked on CodePen so that's super cool too!

:wq

09. September 2015

Simple Match Making Server using WebRTC

With my Ultimate Tic-Tac-Toe Game I've already tackled how to let users manually connect to each other with a unique ID. But now it's time to take it a step further, how do you make it so users can connect with someone they don't know? I figured it out in only a couple lines of JavaScript.

First off, this is all up on github, I'm still working on making things better but the basic functionality is there and it's fresh so I'm writing about it.

The server is using Peer.js, which unfortunately seems to be a dead project, so I'll have to move away from that shortly. The code for a simple Peer server is two lines, they are:

var PeerServer = require('peer').PeerServer;
var server = new PeerServer({port: 9000, path: '/myapp'});

Simple as that. Okay, now we need to track when people connect and disconnect from the server, that's easy enough:

var connected = [];
server.on('connection', function (id) {
  var idx = connected.indexOf(id); // only add id if it's not in the list yet
  if (idx === -1) {connected.push(id);}
});
server.on('disconnect', function (id) {
  var idx = connected.indexOf(id); // only attempt to remove id if it's in the list
  if (idx !== -1) {connected.splice(idx, 1);}
});

So I made an array, then when someone connects to the server I add their id to the array of people connected. That's all I had going for awhile, then I ran into a flaw. How do you know they want to connect to people or aren't already connected to people? This is where I had to add in Express to be a normal node server. So my goal with this is to create two endpoints, one to say you want to connect, and another to remove you from that once you connect. The code for this was a bit more in depth, but still stupid simple:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var readyToConnect = [];

var jsonParser = bodyParser.json();

app.use(bodyParser.json());
app.get('/', function(req,res) {
  return res.json({'connected': connected, 'ready': readyToConnect});
});
app.post('/add-device', jsonParser, function(req,res) {
  readyToConnect.push(req.body);
  return res.json({'response': 'added to collection'});
});
app.get('/remove-device', function(req,res) {
  return res.json({'response': 'removed from collection'});
});
app.listen(8080, function() {
  console.log('listening');
});

I needed to add body-parser so it could parse the request body that the game was sending to the API, it used to be included in Express but it's not anymore. I'm following the same basic concept of the previous connected array, but now I have access to any values I want and I can add and remove things based on endpoints that the app hits when I tell it to. You can see the full server.js file up on github instead of seeing the broken up version as explained here.

What I learned from this is Express is super easy and not some scary voodoo like I thought it was. I didn't even look up documentation for Express, I only have to search on the body-parser issue, it's that simple. I still need to finish the match matching on the game side as it mostly now works and in only 35 lines of code. JavaScript is fun.

:wq

23. August 2015

Optimizing your sites image performance in Drupal

As a developer you can do everything in your power to make your site really slim & fast but when you hand it to the client they could still mess it up in many ways. There are a plethora of things you need to do to keep this from happening, like handling uploaded images better.

I'm able to accomplish this for our clients with a couple very simple modules that you should be using on most (if not on all) of your sites, they are:

Picture & Breakpoints

These two modules work together to handle responsive images. The picture module uses Picturefill to do it's magic. If you don't know about Picturefill it is a polyfill that allows you to use the Picture element today even though only Firefox, Chrome (+ Android Browser) & Opera support it as of writing this.

Setting up these modules is pretty straightforward:

  1. Enable Breakpoints & Picture
  2. Set up your breakpoints by going to /admin/config/media/breakpoints.
    • These are setup just like CSS breakpoints and look like @media(min-width: 640px) Image Breakpoints setup
  3. Configure your new Image Styles breakpoints just made for you.
    • If you breakpoint is a max width of 600px you should scale your image to at max that width.
  4. Edit your display on the content you want to use responsive images to use the Image with sizes format instead of just standard Image. Image with Styles as an option
  5. Then you'll have to choose your sizes which will look like this: (min-width: 0px) (min-width: 640px) (min-width: 1025px) (min-width: 1441px).
  6. Under that you choose which Image Styles you'd like to use. You'll want to choose the ones that breakpoints created for us based on the breakpoints you made.
  7. Choose a fallback image size. I have been using my mid size pictures that are at max ~900px wide. I personally feel like that's large enough it should work for people as a fallback even if it's a little pixelated, that's gotta be better than a 1MB image.
    • When all said and done it should look like this: Image with Styles settings finished
  8. Now when you go to your content it should be switching images based on screen size.
Image API Optimize

Image API Optimize lets you modify the default Drupal image optimization settings. You can choose your compression method and compression amount for your images. This is all helpful things, but there is a patch out there that lets you use this module with TinyPNG. If you've never used Tiny PNG, let me just say it's magic and will make your PNGs crazy small.

Once you have patched and enabled Image API Optimize you will have the options to choose which service you want to use. You can now choose TinyPNG

TinyPNG as option for compression

Once you have that setup you will need to clear your image-cache using drush drush image-flush --all. Then the next time you hit a page with an image it will take a minute because it needs to go out can compress these images, but you should notice they're significantly smaller like 60% smaller at times. Now you don't need to worry about your clients uploading so many PNGs because they need transparencies.

With that very small amount of work we have significantly future proofed the performance of your client's site by making sure all user uploaded pictures are handled properly.

:wq

15. July 2015

Ultimate Tic-Tac-Toe Game

This is a follow up to my P2P Tic-Tac-Toe game I made the other week. In that post I mentioned I was working on a better version of the game and now it's here!

I put this up on CodePen and on this site under my demos and the most up to date version (which at the time of writing the AI is currently broken) is up on GitHub. You can play the game with a friend below!

 

See the Pen Ultimate Tic Tac Toe P2P by Josh Fabean (@fabean) on CodePen.

 

Cool things I'm currently working on is getting a server running to do match making, and making the AI smarter. I feel like with enough rewriting & wizardry I can get the AI unbeatable.

Thanks so much for playing my game I hope you liked it!

:wq

07. July 2015

JavaScript P2P Tic-Tac-Toe

This is a follow up to my P2P chat program I made the other month. I've now morphed it into a game of Tic-Tac-Toe!

Like usual I threw it up on CodePen so you can dig through the code and see how I did it. It was simple and I did most of it in a day or two. The big thing I want to figure out are match-making or at least easier way to connect to your friends.

 

See the Pen Multiplayer Tic Tac Toe Web RTC by Josh Fabean (@fabean) on CodePen.

 

Hope you enjoyed it. I will let you know this was all just an entry into me working on an Ultimate Tic-Tac-Toe game which I've already started and it works beyond knowing when you win and where your next move needs to be.

:wq

29. June 2015

Better Performance With Drupal

Your site's performance is bad, and you should feel bad

When you build a site with Drupal if you don't do it right your users are going to have a bad time. Drupal, like every CMS, when not properly tamed can be slow and use tons of bandwidth. It's 2015, I shouldn't have to explain to you why performance is important and why you should care about it.

There's lots of great things you can and should do to optimize performance. Using these modules you will be able to make your site fast and save your users money on their data bill.

Modules I'm using

Module I've used or heard of and cannot completely give my stamp of approval

In a little over two hours configuring the modules listed above, I was able to gain large performance increases on a very simple site. File size dropped from 985KB to 382KB, speed from 6.67s to 299ms. This was all running locally so I wasn't even using things like Memcache or Varnish which I would suggest for any production site.

alt text

Please be a responsible developer or designer and make websites that perform, no one wants to wait for a site. You absolutely cannot overdue performance! Thanks for helping to make the world a better place.

:wq

10. June 2015

My Grunt.js Boilerplate

The other day I was starting a project and I was to the point where I was needed to create my grunt file and move on with coding the project. The project was my Javascript Chat using WebRTC in case you were wondering. I started pulling from old projects and mashing together a grunt file to my liking for this project. When it was all said and done I ended up spending a good 30 minutes to a hour to get it all worked out working, what a waste of time! Right then I knew I needed to come up with a better solution.

I ended up creating a simple to use grunt boilerplate that I'm going to use when I start all my projects. I plan on this boilerplate being an ever changing thing as needs change and I come up with cool ways to do things. I threw my Grunt Boilerplate on GitHub so you can check it out and use it all you want. There's a how to use there also so I won't waste your time here with that. But I will explain some of the cool tasks it runs.

Tasks in Gruntfile

  • time-grunt: This adds awesome graphs to your grunt builds, what more could you want?
  • load-grunt-tasks: This saves you from having to include grunt.loadNpmTasks('grunt-babel') for each task used.
  • grunt-autoprefixer: This prefixes your css so you can forget adding -webkit- to all your fancy css
  • grunt-babel: Write ES6 code and beyond today and have it compiled down to ES5 so it works in today's browsers.
  • grunt-contrib-connect: While grunt is running you can access your site on 127.0.0.1:9001 saving you time of setting up a local server for each little project.
  • grunt-contrib-jade: Write jade and have it compiled to HTML.
  • grunt-contrib-jshint: run jshint to check your code for errors on build.
  • grunt-contrib-sass: Write sass (pretty self explanatory what this is for and why you need it).
  • grunt-contrib-uglify: you need to compress your JS before you run it in the wild, performance matters punk.
  • grunt-contrib-watch: Watch lets you re-run grunt on each file save.

A couple of things I want to add shortly are:

  • Switch to PostCSS instead of sass.
  • Switch to eslint instead of jshint.
  • Put this in something like Yeoman to make it easier for other people to pick this up and fit their workflow.

So there it is, this is going to save me a lot of time in the future I hope it does for you too. Thanks

:wq

24. May 2015

Chat App Written in Javascript Using WebRTC

Today Nathan Phelps and I decided we would play around with WebRTC to try to do some fun p2p things.

After awhile of playing around we ended up being able to successfully make a p2p chat web app. You can check out javascript-p2p-chat on GitHub. It was written using PeerJS which made it quite easy actually, we spent most of the time rendering it out to the page and making it semi user friendly.

I actually decided to host an working example of it on my site so feel free to play around with it but you'll need to open two browsers or find a friend.

This is still very much a work in progress, I was just too excited to not share with the world.

You will need a browser that supports WebRTC to use this.

alt text

19. May 2015

Drupal Background Image Field Formatter

Ever ran into the issue on Drupal where you want the user to create a piece of content, but the image they upload needs to be a background image so you can do something like background-contain? I ran into this issue last week multiple times while building out the new Code Koalas site[^1]. The first couple of times we just created a custom field template that looked like this:

<?php foreach ($items as $delta => $item): ?>
  <div class="project-image" style="background-image: url(<?php print file_create_url(image_style_path('half_page_image', $item['#item']['uri'])); ?>)"></div>
<?php endforeach; ?>

There's nothing wrong with the above approach, but it seemed repetitive to do the same thing over and over again each time we needed this, because of our designer we needed this a lot. That's when I started thinking maybe there was some sort of module creating a new field type, but then I realized it just needed to be a field formatter for the image field. That's when I found the module Background Image Formatter, but that only lets you use that image and attach it to a css selector. That's not what I needed, I needed a div that was the background image. That's when I'd like to say I found the module I really needed, Simple Background image formatter, but I didn't find that module until I have completely recreated that module myself[^2].

The module Simple Background image formatter, is fantastic! It does exactly what I needed, it removes the need for tons of custom field templates.

Once you have the module installed, go to your display settings for your content type, on your image field open the formatter options:

alt text

Once you do that, you'll want to edit the settings to make sure you're adding the classes you like.

alt text

You can choose your image style, whether to output as CSS or an inline style on a div, and put css classes on your div. I also am using Display Suite and I choose expert template mode, and leave it blank. I do this because otherwise this div you're making will be wrapped in another div, and that isn't want I wanted.

Once you do all that here is the final results!

alt text

Now you can make background images a breeze with Simple Background image formatter.

[^1]: Site isn't launched yet, sorry to disappoint. [^2]: I seriously created the exact same module by myself, that guy beat me by one month.

07. May 2015

JavaScript ES6 for-of vs for-in

Looping in javascript is the best thing ever and I do it all day everyday. I just stumpled upon some of the new ES6 iterators and one stuck out to me a lot. It's called the for-of loop and it much like to a for-in but with one major improvement.

The syntax for both are the same, as shown below:

//ES5
var myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value of myArray) {
  console.log(value);
}

//ES6
let myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value in myArray) {
  console.log(value);
}

Okay, easy enough so what is the difference right? The difference is in the output.

var myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value of myArray) {
  console.log(value);
  // outputs 1,2,3,4
}

let myArray = ['cheddar','provolone','swiss','parmesan'];
for (var value in myArray) {
  console.log(value);
  // outputs 'cheddar','provolone','swiss','parmesan'
}

Do you get the difference? I've always been writing console.log(myArray[value]) to output what for-in outputs out of the box. It's not so life changing change, but it sure is welcomed by me and I appreciate the couple keystrokes this will save me.

Edit May 19, 2015: I did find one thing that might be bad/weird about the for-in loop. It's just a reference to the value and cannot be used to modify the original array.