Warning: Cannot modify header information - headers already sent by (output started at /home/coryandrob/coryschires.com/wp-config.php:2) in /home/coryandrob/coryschires.com/wp-includes/feed-rss2.php on line 8
Cory Schires http://coryschires.com Just another WordPress weblog Sat, 18 Aug 2012 22:57:05 +0000 en hourly 1 http://wordpress.org/?v=3.0 Allowing customers to manually pay invoices with Stripe http://coryschires.com/allowing-customers-to-manually-pay-invoices-with-stripe/ http://coryschires.com/allowing-customers-to-manually-pay-invoices-with-stripe/#comments Sat, 18 Aug 2012 22:38:47 +0000 Cory Schires http://coryschires.com/?p=451 Problem

Stripe doesn’t offer a lot of flexibility with payment options. You can easily process one-time payments or setup recurring, automatic payments on a monthly/annual billing cycle. But if you’re looking to do something more complicated, things can get a little tricky.

For business-to-business startups, such as Scholastica, your customers often (and unfortunately) will not agree to any automated billing solution. Instead, because of annoying bureaucratic constraints, they need to review an invoice prior to making any sort of payment.

Unfortunately, Stripe does not support this type of manually billing workflow. And so the question: How can you use Stripe to create invoices but allow customers to manually pay them after the invoice is created?

Goals

An ideal solution would leverage Stripe’s built-in invoicing system rather than reimplementing some sort of internal invoice object, line items, etc. Stripe has a perfectly good invoicing process; if possible, we don’t want to recreate all that work, manage two separate payment processes, duplicate logic, etc. In short, a manually paid invoice should as much as possible resemble an automatically paid invoice with one exception: the customer should be allowed to review the invoice before approving any charges to their card.

Solution

Allow your customer to add their card in the usual fashion (i.e. they fill in whatever card information you’re collecting, click save, and you send a post to Stripe creating a new customer object). You’ll also want to add an optional checkbox which says something like “Don’t bill this card automatically”. By ticking this checkbox, customers can opt out of automatic billing.

As far as Stripe knows, a manually billed customer is no different from an automatically billed customer. Their card is stored normally and they can be subscribed to whatever plan makes sense for your app.

Now, here’s where things get interesting. When it’s time for your customer to pay their invoice, Stipe will issue a webhook one hour before charging their card. From the Stripe documentation:

Once an invoice is created, payment is automatically attempted. Note that the payment, while automatic, does not happen exactly at the time of invoice creation. If you have configured webhooks, the invoice will wait until one hour after the last webhook is successfully sent (or the last webhook times out after failing).

In your code, listen for that invoice.created webhook and, when it’s received, immediately mark the invoice as “closed”. This will prevent Stripe from attempting to charge the customer’s card. Again quoting from the Stripe documentation:

[The closed boolean determines] whether or not the invoice is still trying to collect payment. An invoice is closed if it’s either paid or it has been marked closed. A closed invoice will no longer attempt to collect payment.

Perhaps more importantly, however, prematurely closing the invoice gives you a easy an easy way to determine which invoices require manual payment. For example, your method might look something like:

    def needs_manual_payment?
      closed? && !paid?
    end
  

This is necessary for writing conditional logic (e.g. showing manually billed customers different views, etc).

Step one accomplished: Your customer will not be automatically billed. Next you’ll need to give them a way to manually pay the prematurely “closed” invoice. Exactly how this should work depends somewhat on the needs of your app. At a high level, however, you’ll want to create a “Pay Invoice” button, which when clicked:

  • Charges a one-time payment to your customer’s card equal the total amount due for the unpaid invoice.
  • Marks the invoice as “paid”.
  • Emails the customer a receipt.

Finally, because at least some of your customers will not be automatically billed, you’ll want to create an admin page where you can view unpaid invoices. This will make it easier to monitor outstanding invoices.

]]>
http://coryschires.com/allowing-customers-to-manually-pay-invoices-with-stripe/feed/ 0
Ten tips for writing better Cucumber steps http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/ http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/#comments Sun, 01 Jan 2012 23:08:19 +0000 Cory Schires http://coryschires.com/?p=420 1. Use flexible pluralization.

Add a ? immediately following the pluralized word:

        Then /^the users? should receive an email$/ do
          # ...
        end
    

The ? specifies that your looking for zero or more of the proceeding character. So the above example will capture both user and users.

2. Use non-capturing groups to help steps read naturally.

You can create non-capturing groups by adding a ?: to the beginning of a otherwise normal group (e.g. (?:some text) rather than (some text)). This is treated exactly like a normal group except that the result will is not captured and thus not passed as an argument to your step definition. This often useful in conjunction with alternation:

        And /^once the files? (?:have|has) finished processing$/ do
          # ...
        end
    

Or another pattern I use regularly:

        When /^(?:I|they) create a profile$/ do
          # ...
        end
    

3. Consolidate step definitions by capturing optional groups.

Often I find myself writing essentially the same step with both positive and negative assertions. You can remove this duplication by capturing an optional group:

        Then /^I should( not)? see the following columns: "([^"]*)"$/ do |negate, columns|
          within('table thead tr') do
            columns.split(', ').each do |column|
              negate ? page.should_not(have_content(column)) : page.should(have_content(column))
            end
          end
        end
    

Here we’re capturing an optional group (note ( not)? using the ? mentioned above). We then pass that into our step as the negate variable which we can use to write conditional assertions.

4. Not all matched phrases need to be surrounded by quotes.

Don’t assume that matched phrases must (or should) be enclosed in double quotes. Often quotes are a good idea. They make it visually clear which phrases will be passed to the step definition. For example:

        Given I have "potatoes" in my cart
    

That’s reasonable. The quotes highlight the parts that change without hurting readability. But sometimes, quotes are just poor style:

        Given I have "7" items in my cart
    

It should be pretty obvious that the number is variable. The quotes add nothing except noise. A better step would read:

        Then /^I have (\d+) items? in my cart$/ do |item_count|
          item_count.to_i.times { ... }
        end
    

5. Use transforms to make smarter, DRYer regular expressions.

There’s an opportunity to refactor the previous example. Do you see it? Cucumber passes everything as a string, so you must remember to convert types within your step definition (e.g. above we use to_i to transform item_count into a proper integer). That’s annoying and easy to forget.

Fortunately, Cucumber gives us a way to avoid this peskiness by using Transform:

        CAPTURE_A_NUMBER = Transform /^\d+$/ do |number|
          number.to_i
        end
    

And we can use this in our steps:

        Then /^I have (#{CAPTURE_A_NUMBER}) items? in my cart$/ do |item_count|
          item_count.times { ... }
        end
    

Not only have we removed the need to call to_i but we’ve also moved our regex into a reusable constant.

6. Define methods to DRY up your step definitions.

Sometimes it’s a good idea to remove duplication by defining methods. For example, it’s common to define a current_user method:

        def current_user
          User.find_by_email('current_user@example.com')
        end
    

Similarly, if you find yourself wrapping several steps with the same logic, you might consider making a helper method. On Scholastica, we test a lot of lightboxes using of this method:

        def within_lightbox(opts = {sleep: 0} )
          sleep(opts[:sleep])
          within_frame("prettyPhotoIframe") { yield }
        end
    

And our step definitions stay nice and clean:

        Then /^some stuff should be visible in the lightbox$/ do
          within_lightbox { page.should have_content('Some Stuff') }
        end
    

By convention, these methods should live in features/support/world_extensions.rb and be included in the Cucumber World module. But keep in mind this is a tradeoff: you’re removing duplication but adding indirection. You should be reluctant to define methods until the code makes it very obvious that it’s a good idea.

7. Use steps within steps.

Sometimes it’s useful to call steps within steps. Another example from Scholastica:

        When /^the request for an expedited decision should be canceled$/ do
          manuscript.should_not be_expedited
          step %{"#{current_user.email}" should receive an email with subject "Expedited decision request canceled"}
        end
    

But don’t go crazy, it’s better to use the capybara methods directly when possible:

        When /^I update the email template to read "([^"]*)"$/ do |text|
          fill_in("email_template[text], with: text)
          click_button("Save changes and close")
          # Rather than...
          # step %{I fill in "email_template[text]" with "#{text}"}
          # step %{I press "Save changes and close"}
        end
    

8. Improve readability with unanchored regular expressions.

Most step definitions look something like:

        Given /^I am an admin user$/ do |item_count|
          # ...
        end
    

Note we’re using ^ and $ to anchor our regex to the start and end of the captured string. This ensures the regular expression exactly matches “I am an admin user” (i.e. allows no additional words at the beginning or end of the step). Most of the time, this is exactly what want.

Occasionally, however, it makes sense to omit the final $. Take this step for example:

        Then /^wait (\d+) seconds/ do |seconds|
          sleep(seconds.to_i)
        end
    

Now you can use this definition to write flexible, expressive steps:

        Then wait 2 seconds for the revenue statistics to finish loading
        Then wait 5 seconds while the document is converted
    

9. When your steps must include data, use tables.

Generally, steps should be human readable and that means they shouldn’t include loads of cryptic data. But sometimes, you have no other choice. In those cases, use tables to clearly represent the data:

        Given "Frankie's Hams" are selling for $25:
        And the following orders have been placed:
          | buyer email      | quantity |
          | eddy@example.com | 3        |
          | matt@example.com | 2        |
    

Using tables within your step definitions can get a bit tricky. I use this helper method but you should really read the relevant source code and figure out what makes sense for your application.

10. Don’t get carried away and spoil a good thing.

As you use these tips, remember that tests should favor clarity over cleverness. In other words, if you’re removing a small amount of duplication but adding a lot of complexity, that’s a poor tradeoff. Here’s an example from Scholastica:

        Given /^(?:I|they) have opened (?:a|an) ([^\s]+) invitation$/ do |invitation_type|
          invitation = Factory("#{invitation_type}_invitation".to_sym, recipient: current_user, to: current_user.email)
          reset_mailer
          eval "ApplicationMailer.invite_#{invitation_type}(invitation).deliver"
          open_email(current_user.email)
        end
    

This steps allows us to write both Given I have opened a reviewer invitation and Given I have opened an editor invitation. I’d say this step is borderline too complex (lots of interpolation and an eval). Maybe it would be better to just write two separate steps? Remember no one is testing your tests so don’t fuck around. A little bit of duplication is not the end of the world.

]]>
http://coryschires.com/ten-tips-for-writing-better-cucumber-steps/feed/ 3
Moving your application to Heroku http://coryschires.com/moving-your-application-to-heroku/ http://coryschires.com/moving-your-application-to-heroku/#comments Tue, 20 Sep 2011 19:11:27 +0000 Cory Schires http://coryschires.com/?p=415 Recently, I moved an app from Rack Space to Heroku. Everything went well except for a few hangups.

Migrating your database.

My app currently used MySQL and, as you probably know, Heroku love Postgres. So how do we get this data up to Heroku?

One option would be to use the taps gem to import the MySQL data into Postgres. But that didn’t work so well for me. The gem seemed to fail arbitrarily, leaving me unsure about the fidelity of my data.

Another option, use Heroku’s Amazon RDS addon. It was a little painful to setup but not terrible and there’s plenty of good documentation.

Fixing bad encodings.

Once I got my database migrated, I noticed a new issue. Little �’s were peppered throughout my copy. That’s a bad encoding since, apparently, I’m using a different version of MySQL. So I wrote a little script to replace bad encodings with HTML entities.

It’s not exhaustive, but it’s solid and should be easy to adapt if needed.

Things to watch out for.

  • Does your app use SSL? If so, plan ahead since that can take a few days to work out.
  • If you’re using sendgrid, be sure to choose a plan that won’t cap out and start throwing errors.
  • Don’t forget to set both your MX and A records.
  • Don’t forget to setup New Relic and Hoptoad before switching over. You’ll probably encounter some errors and it’s better to know about them.
]]>
http://coryschires.com/moving-your-application-to-heroku/feed/ 0
Adding default configuration options to Paperclip http://coryschires.com/add-default-configuration-options-to-paperclip/ http://coryschires.com/add-default-configuration-options-to-paperclip/#comments Sun, 24 Jul 2011 00:02:40 +0000 Cory Schires http://coryschires.com/?p=408 Using paperclip, you’ll often put something like this in your models:

      has_attached_file :article_text,
        :storage => :s3,
        :s3_credentials => {
          :bucket => ENV['AS3_BUCKET'],
          :access_key_id => ENV['AS3_ACCESS_KEY_ID'],
          :secret_access_key => ENV['AS3_SECRET_ACCESS_KEY']
        }
       :s3_permissions => :private,
       :processors => [:manuscript_converter],
       :path => "manuscript/:id/:uploaded_manuscript_filename"
    

Many of these settings will be repeated in every paperclip’d model. You can easily remove that duplication by adding an initializer. In config/initializers/paperclip_defaults.rb:

      Paperclip::Attachment.default_options.merge!(
        :storage => :s3,
        :s3_credentials => {
          :bucket => ENV['AS3_BUCKET'],
          :access_key_id => ENV['AS3_ACCESS_KEY_ID'],
          :secret_access_key => ENV['AS3_SECRET_ACCESS_KEY']
        }
      )
    

And now you can remove those options from all your models – separating the parts that change from the parts that stay the same.

I had trouble finding this online and had to dig through the source code to figure it out. So maybe it will help someone else save a little time.

]]>
http://coryschires.com/add-default-configuration-options-to-paperclip/feed/ 0
Maintaining a reading list on GitHub http://coryschires.com/maintaining-a-reading-list-on-github/ http://coryschires.com/maintaining-a-reading-list-on-github/#comments Mon, 21 Feb 2011 21:45:16 +0000 Cory Schires http://coryschires.com/?p=382 Like any decent programmer, I spend a lot of time reading. For the most part it runs in cycles: read a bunch of stuff, apply what you’ve learned, read a bunch more, and so on. This is a pretty typical pattern as becoming a strong developer requires a good mix of learning and doing. So, inspired in part by Apprenticeship Patterns, I’ve decided to start maintaining a reading list.

Screenshot of reading list

Some simple ground rules for myself.

  • List should be publicly available on github.
  • Be honest about what books I’ve read, partially read, and plan to read.
  • Write a few sentences about each book – mostly for myself but also for anyone who might be interested.
  • Only include books related to development, user experience design, and entrepreneurship.
  • Include screencasts as well since that’s how I do much of my learning.

I’ve already noticed some benefits.

Although it’s only been a short time, I can already attest to the usefulness of keeping track of what you’ve read. Just building the list requires going back through all the stuff you’ve read and watched over the past few years. It’ll get you thinking about how you learn, including some really interesting questions:

  • How have your interests moved between topics?
  • What topics do you keep coming back to?
  • What periods were most productive?
  • What topics required a few books before you really understood?
  • What type of books are most useful for the way you learn? (e.g. Do you learn better with lots of examples or would you rather read a short book twice?)
  • Were any of the books disappointing? Why?

I think it’s important that your list be more than a catalogue of titles and author names. You should take the time to reflect on why the book mattered (i.e. what did you take away from the read?). While this means writing a few sentences for each entry, don’t get too fixated. There’s no reason to write a summary or book review. The writeup is just to get you thinking broadly about the book.

And you should do it too.

Finally, I’d like to see other developers maintaining a reading list – specifically on GitHub. It’d be awesome if I could look up serious developers to check out what they’re reading and, more importantly, what they recommend. It’d be a nice adjunct to reading their code.

View my reading list on Github

]]>
http://coryschires.com/maintaining-a-reading-list-on-github/feed/ 2
jQuery Splatter Plugin http://coryschires.com/jquery-splatter-plugin/ http://coryschires.com/jquery-splatter-plugin/#comments Wed, 09 Feb 2011 21:42:30 +0000 Cory Schires http://coryschires.com/?p=373 Splatter is a jQuery plugin which applies a random position, size, and color to elements on a page. The most basic implementation adds randomly colored and positioned asterisks to the element:

simple_example

To see some working examples, check out the demo page.

Basic usage.

Add these scripts in the head element of your page:

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="jquery.splatter.js" type="text/javascript" charset="utf-8"></script>
    

Invoke the plugin, specifying configuration options as needed. For example, pass an array of splats if you’d like to use words rather than asterisks:

        $('#word_splatter').splatter({
          min_font_size: 20,
          max_font_size: 50,
          splats: ["Lorem", "Ipsum", "Dolor", "Sit", "Amet", "Consectetur", "Adipisicing", "Elit", "Sed", "Do", "Eiusmod", "Tempor", "Incididunt", "Ut", "Labore", "Et", "Dolore", "Magna", "Aliqua", "Ut", "Enim", "Ad", "Minim", "Veniam", "Quis", "Nostrud", "Exercitation", "Ullamco", "Laboris", "Nisi", "Ut", "Aliquip", "Ex", "Ea", "Commodo", "Consequat"]
        });
    

Which creates:

Splatter example using words

Configuration options.

Splatter has lots of configuration options but most of them are pretty simple and none of them are required:

        $('#splatter_box').splatter({
          custom_attributes: [],      // specify custom attributes to add to splats which can be used to store data
          colors: [],                 // specify the colors to be randomly applied to the splats
          splats: [],                 // specify strings to be used as splats – defaults to *
          hover_on: function() {},    // add a custom function to be called when hovering on a splat
          hover_off: function() {},   // add a custom function to be called when hovering off a splat
          splat_count: 20,            // number of splats that will be drawn
          min_font_size: 20,          // minimum font size for splats
          max_font_size: 300,         // maximum font size for splats
          height: $(window).height(), // height of splatter
          width: $(window).width()    // width of splatter
        });
    

Most of these should be fairly obvious but let’s go into a bit more detail on how to use custom attributes. Custom attributes allow you to apply data attributes with random values to each splat. They are specified as an array of objects:

        $('#splatter_box').splatter({
          custom_attributes: [
            { name: "data-hover_color", values: ['#f68a00', '#069', '#a70'] },
            { name: "data-slide_position", values: ['20', '50', '100'] }
          ]
        });
    

Each custom attribute object should have two keys: a name and values. The name will be used as the attribute’s name. The values key takes an array of possible values. The actual value for any given custom attribute is randomly selected from the values array.

So the the above example might create splats that look like:

        *
        *
    

Often custom attributes work in conjunction with custom hover events, allowing you to use jQuery to fetch these custom values and do something interesting (e.g. fade in a different color, animate a splats position, or make a splat randomly rotate). For example, let’s create 100 splats in shades of gray that fade into random colors on hover:

        $('#animated_colors').splatter({
          width: 700,
          height: 250,
          splat_count: 100,
          colors: ['#ccc', '#e0e0e0', '#333', '#666', '#999'],
          custom_attributes: [
            { name: "data-hover_color", values: ['#f68a00', '#069', '#a70', '#090', '#ff1493', '#0066CC', '#ff1493', '#F0E356'] }
          ],
          hover_on: function(splat) {
            var original_color = splat.css('color');
            var hover_color = splat.attr('data-hover_color')
            splat.css('color', hover_color).attr('data-hover_color', original_color);
          },
          hover_off: function(splat) {
            var original_color = splat.css('color');
            var hover_color = splat.attr('data-hover_color');
            splat.css('color', hover_color).attr('data-hover_color', original_color);
          }
        });
    

And add some CSS3 to handle the color transitions:

        .splatter_box .splat {
          transition: color 0.5s linear;
          -moz-transition: color 0.5s linear;
          -o-transition: color 0.5s linear;
          -webkit-transition: color 0.5s linear;
          cursor: pointer;
        }
    

Which will create something like:

Example with color transitions

If you need additional help understanding the various configuration options, check out the live demos as well as the unit tests.

Download the project from GitHub

]]>
http://coryschires.com/jquery-splatter-plugin/feed/ 17
Making Breakout with Processing.js. http://coryschires.com/breakout-clone-in-processing-js/ http://coryschires.com/breakout-clone-in-processing-js/#comments Wed, 19 Jan 2011 20:23:41 +0000 Cory Schires http://coryschires.com/?p=349 source code.]]> As few months back, I spent the weekend reverse engineering breakout with Processing.js. If you haven’t had a chance to spend some time with this language, you really should. Processing is an easy-to-learn, open-source programming language for making images, animation, and interactions.

Click the image below to play the demo. Control paddle using your mouse.


Breakout Screenshot

Here’s a high level overview of the code. Like any processing script, we start by initializing some variables:

      // --- colors ---
      color black = color(0);
      color bright_green = color(110,212,111);
      color pink = color(190,81,163);
      color purple = color(97,81,190);
      color light_blue = color(142, 185,234);
      color yellow = color(212,197,110);

      // --- initialize arrays for bricks ---
      Brick[] pink_bricks = new Brick[10];
      Brick[] green_bricks = new Brick[10];
      Brick[] navy_bricks = new Brick[10];
      Brick[] blue_bricks = new Brick[10];
      Brick[] yellow_bricks = new Brick[10];
      array[] bricks = new array[5];
    

Then we do some configuration in our setup block:

      void setup() {
       size(400,400);
       frameRate(80);

       // initialize game, paddle, ball
       game = new Game();
       paddle = new Paddle();
       ball = new Ball(200, 375);

       // initialize bricks
       for (int a=0; a<10; a++) {
           pink_bricks[a] = new Brick(a*40, 0, pink);
           green_bricks[a] = new Brick(a*40, 20, bright_green);
           navy_bricks[a] = new Brick(a*40, 40, purple);
           blue_bricks[a] = new Brick(a*40, 60, light_blue);
           yellow_bricks[a] = new Brick(a*40, 80, yellow);
       }

       // combine all bricks into single array of arrays
       bricks[0] = pink_bricks;
       bricks[1] = green_bricks;
       bricks[2] = navy_bricks;
       bricks[3] = blue_bricks;
       bricks[4] = yellow_bricks;
      }

Then we have a draw loop. This is an endless loop where we can place our game logic:

      void draw() {
       background(black);

       // draw bricks
       game.build(bricks);

       // draw paddle and ball
       paddle.display(mouseX);
       ball.display(); 

       // animate ball
       if (game.active) {
           ball.move();
       } else {
           ball.rest_on_paddle(paddle);
           game.reset(bricks);
           $('#messages #start').show();
       }

       // if ball goes off screen
       if ( ball.off_screen() ) {
           game.active = false;
       }

       // if ball hit paddle
       if ( ball.hit_paddle(paddle) ) {
           ball.rebound_off(paddle);
       }

       // if ball hits bricks
       if (ball_y <= 100) {
           hit_brick = game.determine_colision(ball, bricks);

           if (hit_brick.is_active()) {
               hit_brick.deactivate();
               ball.bounce_off_brick(hit_brick);
               game.increment_points(10);
           }
       }
      }
    

Finally we have a simple keyPressed function to allow the user to pause the game.

      void keyPressed() {
       // when user presses space bar
       if (key == 64) {
           if ( ball.is_in_start_position() ) {
               ball.move_upward(); // start game
               game.active = true;
               $('#messages #start').hide();
           } else {
               ball.toggle_pause(); // pause/resume game
           }
       }
      }
    

From here on out, it's pretty simple. Everything is object oriented in a sensible manner. First, we have a game class. This holds all the application wide functionality as well as things that generally don't fit well into other classes but also don't merit a separate class (e.g. points):

      class Game {
       int points;
       int level;
       boolean active;

       Game() {
           points = 0;
           level = 1;
           active = false;
       }

       void build(bricks) {
           for (int i=0; i < bricks.length; i++) {
               for (int x=0; x < bricks[i].length; x++) {
                   bricks[i][x].display();
               }
           }
       }

       void reset(bricks) {
           for (int i=0; i < bricks.length; i++) {
               for(int x=0; x < bricks[i].length; x++) {
                   brick = bricks[i][x];
                   brick.brick_active = true;
                   brick.brick_color = brick.original_color;
               }
           }
       }

       void increment_points(points_earned) {
           points += points_earned;
           $('#game_stats #points span').html(points);
       }

       void determine_colision(ball, bricks) {
           y = ball.show_ball_y();
           x = ball.show_ball_x();     

           // find brick row based on ball location
           if      (y >= 0 && y <=  20) { row = 0; }
           else if (y > 20 && y <=  40) { row = 1; }
           else if (y > 40 && y <=  60) { row = 2; }
           else if (y > 60 && y <=  80) { row = 3; }
           else if (y > 80 && y <= 100) { row = 4; }

           // find brick column based on ball location
           if      (x >=  0 && x <=  40) { col = 0; }
           else if (x >  40 && x <=  80) { col = 1; }
           else if (x >  80 && x <= 120) { col = 2; }
           else if (x > 120 && x <= 160) { col = 3; }
           else if (x > 160 && x <= 200) { col = 4; }
           else if (x > 200 && x <= 240) { col = 5; }
           else if (x > 240 && x <= 280) { col = 6; }
           else if (x > 280 && x <= 320) { col = 7; }
           else if (x > 320 && x <= 360) { col = 8; }
           else if (x > 360 && x <= 400) { col = 9; }

           return bricks[row][col];
       }
      }
    

Next, we have a ball class...

      class Ball {

       Ball(temp_ball_x, temp_ball_y) {
           ball_diameter = 10;
           ball_x = temp_ball_x;
           ball_y = temp_ball_y;
           speed_x = 0;
           speed_y = 0;
           speed_max = 4;
           pre_pause_speed  = [0,0];
       }

       void display() {
           noStroke();
           fill(bright_green);
           ellipse(ball_x, ball_y, ball_diameter, ball_diameter);
       }

       void move() {
           // make ball bounce off ceiling
           if (ball.edge("top") < 0) {
               speed_y = speed_y * -1;
           }
           // make ball bounce off either sidewall
           if ( ball.edge("left") < 0 || ball.edge("right") > width ) {
               speed_x = speed_x * -1;
           }
           // animate ball
           ball_x += speed_x;
           ball_y += speed_y;
       }

       void toggle_pause() {
           if (speed_x == 0 && speed_y == 0) {
               speed_x = pre_pause_speed[0];
               speed_y = pre_pause_speed[1];
               $('#messages #pause').hide();
           } else {
               pre_pause_speed[0] = speed_x;
               pre_pause_speed[1] = speed_y;
               speed_x = 0;
               speed_y = 0;
               $('#messages #pause').show();
           }
       }

       void rest_on_paddle(paddle) {
           // stop ball from moving
           speed_x = 0;
           speed_y = 0;
           // constrain resting position to keep ball on center of paddle
           resting_position = constrain(mouseX, paddle.half_width(), width - paddle.half_width());
           // place ball atop paddle
           ball_y = 375;
           ball_x = resting_position;
       }

       void is_in_start_position() {
           if ( ball_y == 375 && (speed_y == 0 && speed_x == 0) ) {
               return true;
           } else {
               return false;
           }
       }

       void move_upward() {
           speed_x = 0;
           speed_y = -3;
       }

       void bounce_off_brick(brick) {
           bcp = brick.center_point();
           distance_at_bounce = dist(bcp[0],bcp[1], ball_x,ball_y);

           if (distance_at_bounce >= 20) {
               speed_x = speed_x * -1;
           } else {
               speed_y = speed_y * -1;
           }
       }

       void edge(edge) {
           if (edge == "top") {
               ball_edge = ball_y - 5;
           } else if (edge == "bottom") {
               ball_edge = ball_y + 5;
           } else if (edge == "left") {
               ball_edge = ball_x - 5;
           } else if (edge == "right") {
               ball_edge = ball_x + 5;
           } else {
               return console.log("Argument Error - Valid arguements: top, bottom, left, right");
           }
           return ball_edge;
       }

       void off_screen() {
           if (ball_y > height) {return true;} else {return false;}
       }

       void hit_paddle(paddle) {
           if (ball_y > paddle.edge("top") && (ball_x > paddle.edge("left") && ball_x < paddle.edge("right") )) {
               return true;
           } else {
               return false;
           }
       }

       void rebound_off(paddle) {
           // cacluate distance between point of contact and center of paddle
           bounce_point = dist(
               ball_x, paddle.show_paddle_y(), // point of contact
               paddle.show_paddle_x(), paddle.show_paddle_y() // center of paddle
           );

           // calculate rebound angle relative to bounce point
           if (ball_x < paddle.show_paddle_x()) {
               speed_x = (bounce_point * 0.05) * -1;
           } else {
               speed_x = bounce_point * 0.05;
           }

           // calculate y speed relative to rebound angle
           speed_y = (speed_max - abs(speed_x)) * -1;
       }

       void show_ball_x() {
           return ball_x;
       }

       void show_ball_y() {
           return ball_y;
       }

      }
    

Then a brick class...

       color brick_stroke;
       color brick_color;
       color original_color;
       int brick_width;
       int brick_height;
       int brick_x;
       int brick_y;
       boolean brick_active;   

       Brick(temp_brick_x, temp_brick_y, temp_color) {
           brick_stroke = black;
           brick_color = temp_color;
           brick_width = 40;
           brick_height = 20;
           brick_x = temp_brick_x;
           brick_y = temp_brick_y;
           brick_active = true;
           original_color = temp_color;
       }

       void display() {
           rectMode(CORNER);
           stroke(brick_stroke);
           fill(brick_color);
           rect(brick_x, brick_y, brick_width, brick_height);
       }

       void is_active() {
           return brick_active;
       }

       void deactivate() {
           brick_active = false;
           brick_color = black;
       }

       void center_point() {
           return [brick_x + brick_width/2, brick_y + brick_height/2 ];
       }
      }
    

Finally, a paddle class...

      class Paddle {
       int paddle_width;
       int paddle_height;
       color paddle_color;
       float paddle_x;
       float paddle_y;

       Paddle() {
           paddle_width = 80;
           paddle_height = 7;
           paddle_color = bright_green;
           paddle_x = width/2;
           paddle_y = 385;
       }

       void display() {
           // determine paddle_y and constrain so paddle cannot leave screen
           paddle_x = constrain(mouseX, paddle_width/2, width - paddle_width/2);

           // draw paddle
           rectMode(CENTER);
           noStroke();
           fill(paddle_color);
           rect(paddle_x, paddle_y, paddle_width, paddle_height);
       }

       void edge(edge) {
           if (edge == "left") {
               return paddle_x - (paddle_width/2);
           } else if (edge == "right") {
               return paddle_x + (paddle_width/2);
           } else if (edge == "top") {
               return paddle_y -5;
           } else {
               return console.log("Argument Error - Valid arguements: left, right, top");
           }
       }

       void half_width() {
           return paddle_width/2;
       }

       void show_paddle_x() {
           return paddle_x;
       }

       void show_paddle_y() {
           return paddle_y;
       }
      }
    

Download the project from Github

]]>
http://coryschires.com/breakout-clone-in-processing-js/feed/ 1
Dynamic CSS3 Buttons with LESS http://coryschires.com/dynamic-css3-buttons-with-less/ http://coryschires.com/dynamic-css3-buttons-with-less/#comments Sun, 04 Jul 2010 20:03:39 +0000 Cory Schires http://coryschires.com/?p=334 There’s been a lot of buzz surrounding CSS3 buttons – including some really great tutorials. The concept behind a basic button, however, is pretty simple:

  1. Apply a subtle background gradient
  2. Add some rounded corners
  3. Add text shadows – optionally
  4. Add a thin border – optionally
  5. Add a box shadow – optionally
  6. Repeat this process for active and hover states

For sure, making good buttons means doing these steps well. But programmatically, this is pretty damn simple. The difficultly lies in design not code.

With that in mind, let’s look at how we might use a CSS abstraction language, like LESS, to boil these steps down and make our button code super flexible. But first, let’s take a look at CSS abstraction languages more generally.

What’s a CSS abstraction language?

An abstraction language is a wrapper that adds powerful functionally to the standard CSS language. Have you ever wanted to set a variable in your stylesheet or do some math? Abstraction languages make this possible.

Now, if you’re like me, you might be thinking: “If I need to do multiplication in a stylesheet something’s gone terribly wrong.” Keep reading. Maybe you’ll change your mind.

How do I use a CSS abstraction language?

Normally, abstraction languages require a supporting back-end language. This supporting language parses your abstracted code and generates normal, static stylesheets at runtime. Ruby, for example, does exactly this to turn SASS into CSS.

That’s cool, but for most projects we don’t need a powerful back-end framework. And there’s certainly no reason start using one just to make your stylesheets more dynamic. This means, by and large, abstraction languages just aren’t viable except in large, complicated projects.

But LESS is about to change all that. Alexis Sellier has recently developed a pure JavaScript implementation. This means no back-end language is required. Just follow these simple steps:

  1. Give your stylesheet a mime type of .less rather than .css
  2. Add an attribute of rel="stylesheet/less" rather than rel="stylesheet"
  3. Include the less.js script below all stylesheets in your header.

With that finished, your header should include something like:

        <link rel="stylesheet/less" href="buttons.less" type="text/css" charset="utf-8" >
        <script src="less-1.0.30.min.js" type="text/javascript" charset="utf-8"></script>
    

And now we have access to some pretty awesome features. Like setting variables and performing operations:

        @pagewrap_width: 970px
        @accent_color: #2BBF26;        

        section {
          @pagewrap_width - 300px
          color: @accent_color - #f0f0f0;
        }
    

And that’s just a few of the awesome features. I encourage you to checkout the details and documentation.

How can we use this to make better buttons?

1 Get a nice looking button.

Making a nice button can be tricky, so I recommend using the code posted in one of these excellent tutorials. But if you’d rather roll your own, I suggest this dead simple button making tool.

Whatever your method, just get some CSS and paste it into your LESS equipped stylesheet. In this example, I’ll be using this code:

        /* styles for button color */
        .button {
          color: #fef4e9;
          border: solid 1px #da7c0c;
          background: #f78d1d;
          background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20));
          background: -moz-linear-gradient(top,  #faa51a,  #f47a20);
        }
        .button:hover {
          background: #f47c20;
          background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015));
          background: -moz-linear-gradient(top,  #f88e11,  #f06015);
        }
        .button:active {
          background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a));
          background: -moz-linear-gradient(top,  #f47a20,  #faa51a);
        }

        /* basic styles for button size, padding, etc. */
        .button {
          display: inline-block;
          outline: none;
          cursor: pointer;
          text-align: center;
          text-decoration: none;
          font-size: @font_size;
          line-height: 100%;
          font-family: Helvetica, Verdana, Arial, sans-serif;
          padding: .55em 2em .55em;
          text-shadow: 0 1px 1px rgba(0,0,0,.3);
          -webkit-border-radius: 0.5em;
          -moz-border-radius: 0.5em;
          border-radius: 0.5em;
          -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.2);
          -moz-box-shadow: 0 1px 2px rgba(0,0,0,.2);
          box-shadow: 0 1px 2px rgba(0,0,0,.2);
        }
        .button:hover {
          text-decoration: none;
        }
        .button:active {
          position: relative;
          top: 1px;
        }
    

And our buttons will look like:

2 Extract the important stuff into variables.

That’s a lot of CSS but let’s focus on what actually matters: font color, border radius, border color, padding, and background gradients.

Let’s move these values into variables. It’s a good convention to place them at the top of your stylesheet like so:

        /* basic button variables */
        @background_color: #f78d1d;
        @hover_background_color: #f47c20;
        @border_radius: 0.5em;
        @font_size: 14px;
        @font_color: #fef4e9;
        @button_padding: 0.55em 2em;
        @border_color: #da7c0c;

        /* background color gradients for each state */
        @normal_background_top: #faa51a;
        @normal_background_bottom: #f47a20; 

        @hover_background_top: #f88e11;
        @hover_background_bottom: #f06015; 

        @active_background_top: #f47a20;
        @active_background_bottom: #faa51a;

        /* ...previous css with original values substituted for variables... */
    

Now, already that’s a nice improvement. We can easily make changes to our button styles without having to wade through all that CSS. Want rounder corners? Just increase @border_radius.

3 Make a good thing better with high school math.

While we’ve made an improvement, that still feels like too many configuration options for a simple button. Wouldn’t it be nice, for example, if we didn’t have to worry with all those color variations (i.e. border color, background colors, gradients, etc). It would be much better if we could consolidate all those values into a single variable (e.g. @button_color).

Let’s do just that. First, let’s change @background_color to @button_color. We’ll hold this value constant and set all of our other color-related values relative to @button_color. This means we’ll be able to alter one variable — @button_color — and changes will automatically cascade through related variables.

In case you’re confused, I’ll break it down a bit so you can see what’s going on. We’re just doing some simple math with hexcodes:

        /* we've already set these variables */
        @background_color: #f78d1d;
        @border_color: #da7c0c;

        /* if we know that: */
            @button_color - @border_color = #1D1111
        /* then high school algebra says: */
            @border_color = @button_color - #1D1111
    

So we can use this concept to set all our color values relative @button_color. Now our configuration options are looking much leaner:

        /* button configuration options */
        @button_color: #f78d1d;
        @border_radius: 0.5em;
        @font_size: 14px;
        @font_color: #fef4e9;
        @button_padding: 0.55em 2em;

        /* color variables set relative to @button_color.
        You probably don't need to change these. */
        @hover_background_color: @button_color - #031100;
        @border_color: @button_color - #1D1111;

        @normal_background_top: @button_color + #031800;
        @normal_background_bottom: @normal_background_top - #062B00; 

        @hover_background_top: @button_color + #010100;
        @hover_background_bottom: @hover_background_top - #082E08; 

        @active_background_top: @normal_background_bottom;
        @active_background_bottom: @normal_background_top;   

        /* ...previous css with original values substituted for variables... */
    

So now we only need to concern ourselves with five clearly named variables. And we can easily change our style to suit different themes. Change the value of @button_color to #ffb515 and you get yellow buttons complete with CCS3 gradients:

Or change @button_color to #2daebf and @font_size to 22px:

You get the idea. Changing styles couldn’t be easier.

But this is about more than just buttons.

This is just a trivial example of how LESS can make our stylesheets more dynamic. Imagine, for example, WordPress themes where non-developers could alter the entire color scheme by changing a single variable. Or tweak the layout through something like @sidebar_width.

When done well, layouts could even feel a bit like jQuery plugins. Just download the files, change a few configuration options, and you’re ready to roll. This would be especially useful for stylesheets that aren’t too application specific — like wireframe layouts or admin/cms interfaces.

Maybe designers will even start open-sourcing layouts the way developers share plugins? Maybe.

Download the project from GitHub

]]>
http://coryschires.com/dynamic-css3-buttons-with-less/feed/ 6
jQuery swap form value plugin. http://coryschires.com/jquery-swap-form-value-plugin/ http://coryschires.com/jquery-swap-form-value-plugin/#comments Wed, 09 Jun 2010 06:38:06 +0000 Cory Schires http://coryschires.com/jquery-pwap-form-value-plugin/ textarea and input elements, and runs solidly across browsers.]]> Here’s a simple, lightweight plugin to swap default values in a form field. It works with both textarea and input elements, and runs solidly across browsers. For example:

How to make it work.

Just add a swap_value attribute to your element specifying the value you’d like shown in the field:

       <input type="text" name="username" swap_value="username" />
    

And call the plugin like this:

        $("input[swap_value], textarea[swap_value]").swap_value();
    

You can also change the default text colors by passing arguments to the function:

        $("input[swap_value], textarea[swap_value]").swap_value({
			normal_color: '#3E474D',
			default_color: '#BCBCBD'
        });
    

Don’t forget about accessibility.

For accessibility reasons, you should always include labels for each of your form elements. If you don’t want labels cluttering up your view, I suggest you hide them:

        
        
    

Some more powerful alternatives.

There are some similar, although much more powerful, plugins available for swapping form values. If you’re looking something more fully-featured, I suggest you checkout jquery watermark. Also the in-field labels plugin seems pretty awesome.

Of course, the right choice depends on the needs of your application. Better to go with something simple, if that’s all you need.

Download the project from GitHub

]]>
http://coryschires.com/jquery-swap-form-value-plugin/feed/ 0
How to shorten urls with bit.ly in Ruby on Rails. http://coryschires.com/how-to-shorten-urls-with-bit-ly-in-ruby-on-rails/ http://coryschires.com/how-to-shorten-urls-with-bit-ly-in-ruby-on-rails/#comments Tue, 06 Apr 2010 00:20:44 +0000 Cory Schires http://coryschires.com/?p=307 First, let’s make a simple retweet link for our application. To keep our views a little cleaner, we’ll make a helper method in app/helpers/application_helper.rb:

        def twitter_url(resource, tweet_text="Check out this article from my-site.com:")
          tweet_url = root_url.chop + url_for(resource)
          "http://twitter.com/home?status=#{tweet_text} #{tweet_url}"
        end
    

This method just builds a url to twitter and supplies some default text which you may optionally override by passing a second argument. Call it in your view like this:

        <%= link_to "Retweet this post!", twitter_url(@post) %>
    

Now, this method works but it would be much better if we could use shortened urls. So let’s change things a bit in order to use bit.ly — twitter’s preferred url shortening service. Before we write any code…

  1. You’ll need to sign up for bit.ly.
  2. And grap your api key.

With that info on hand, we’re ready to interface with the bit.ly api. Let’s make another helper method also located in app/helpers/application_helper.rb:

        def shorten_with_bitly(url)
          # build url to bitly api
          user = "insert-your-username"
          apikey = "insert-your-api-key"
          version = "2.0.1"
          bitly_url = "http://api.bit.ly/shorten?version=#{version}&longUrl=#{url}&login=#{user}&apiKey=#{apikey}"

          # parse result and return shortened url
          buffer = open(bitly_url, "UserAgent" => "Ruby-ExpandLink").read
          result = JSON.parse(buffer)
          short_url = result['results'][url]['shortUrl']
        end
    

This method uses your credentials to build a url to interface with the bit.ly api. Bitly receives our request and returns a JSON object containing a shortened url. We’ll parse this object, grab the shortened url, and return it.

Finally, we need to change our initial twitter_url method to include url shortening:

        def twitter_url(resource, tweet_text="Check out this article from my-site.com:")
          tweet_url = root_url.chop + url_for(resource)
          tweet_url = shorten_with_bitly(tweet_url) if Rails.env.production?

          "http://twitter.com/home?status=#{tweet_text} #{tweet_url}"
        end
    

This is identical to our original method except we’ve added a new line which calls shorten_with_bitly. This line overwrites the tweet_url variable — replacing the long url with a shortened version. Finally, we’ll include a condition to ensure this only happens in production. This saves us from creating a bunch of useless bit.ly links that point to localhost urls.

Some final points.

  • The shorten_with_bitly method borrows heavily form a ruby snippet posted by Puneet Pandey. Pandey definitely deserves some credit here.
  • If you’re looking for a more robust way to interface with the bit.ly api, checkout this url shortening gem by Nasir Jamal. I’ve never used it but appears to be fully featured and well documented.
]]>
http://coryschires.com/how-to-shorten-urls-with-bit-ly-in-ruby-on-rails/feed/ 2