C64 Game recreated as HTML5 Game

Here's a great interview with the hungarian developer, Kriz, who recreated this old game as closely as he could from scratch. I found it interesting he didn't even try to crack into it and look at the source code. He just watched closely and recreated what he saw. This is the 4th such game he is behind and I hope he keeps going!

Embedded Link

Wizard of Wor
There seems to be a trend of re-creating classic 8-bit games in JavaScript at the moment, including the recent and excellent Survivor. B

Open Sourced Flash Tower Game

Ben Lowry has released all his code for his game InkTd. It is a standard tower style game with a bit of a twist. It gives options for 2 game modes: path mode and another called maze mode with the path being dynamically adjusted to reach the base. Sounds like it deserves porting to html5!

Embedded Link

InkTd Flash game source code released – Emanuele Feronato
Did you ever wonder how a complete tower defense source code looks like? This is your lucky day. A couple of years ago Ben Lowry, also known for being the founder of Playtomic, made a tower defense ga…

Programming Languages as Data Visualization Infographic

Here's a great data visualization timeline showing an individual's programming history: what languages and when and how much. I think it's a very pleasing visual too. He's posted the code to github to play with. Could be a very interesting addition to a bio or resume.

Embedded Link

Zeh Fernando » Blog Archive » Programming platforms I’ve used, 1986-2012
One day I started filling a spreadsheet with all the languages I've used over the years (and with percentages of focus on each one) with the intention of creating a chart. It got bigger than I exp…

WordCamp Presentation Slides: From Photoshop PSD to WordPress Theme

from photoshop to wordpress theme presentation

Here are my slides for my WordCamp Atlanta presentation, From PSD to WordPress Theme: Under the skin:

This presentation covers how to get from a photoshop design to a theme in WordPress. The sample theme I use in the presentation is actually live at http://psd2wp.circlecube.com. I’m not trying to teach css or html here. I more wanted to focus on the process I usually go through in creating a site or theme. Let’s work on this PDS template design called Corporate Clean, which was designed and published by Zsolt Kacso. I saw this done by a drupal theme shop and figured the wordpress world could use the same. (Also check out Corporate Clean for Drupal http://drupal.org/project/corporateclean and download the design they link to on that page: http://mttdownloads.s3.amazonaws.com/projects/kaolti/corporateclean_psds.zip)
corporate clean wordpress theme from photoshop

First, What is a Theme?

It is all the files that control the front-end and visual side of a site. It is all the files that control the front-end and visual side of a site. Major benefit to a theme (or a CMS overall) is separating design and content, which is the goal of standards based web design. Themes are made up of a combination of files: css, html, php, javascript, images…

The basic structure of a theme is usually something like: Header, Content, Aside(s) and Footer.
We know what types of files or templates we need to include in our theme by using the Template Hierarchy is how WordPress determines which template to use on each page. It looks for template files with specific names in the current Theme’s directory and uses the first matching template file listed under the appropriate query section below. (See Joost De Valk’s Anatomy of a WordPress Theme Infographic).

A wordpress specific term that took me a while to get used to was “the loop”

There are many different roads to a WordPress theme.

All themes are not created equal. There are different type and diffrerent qualitiy levels of themes. We can group them into these main areas though (some of which overlap):

  • Free – benefit, it’s FREE. Only problem is there’s not a great vetting process and a lot of themes out there aren’t good quality themes you’d want on your site (even if they look nice from the front).
  • Premium – although WP is open source software as in free, not all themes are free, some will cost you.
  • From Scratch – It is possible to make a theme from the bottom. This could be beneficial if you have something specific you’re not likely to find out there already.
  • Customized – A direction many take is acquiring a theme (be it free or not) and them customizing it to make it suit them. Not a bad if you’re starting from something that is nicely done, and you know how to get from a to b.
  • Standalone – Traditionally all themes were standalone packages, and the theme folder will contain all associated files.
  • Parent-Child – Since WP 2.7 we’ve had the ability to have parent-child relationships in theming! This means that you can have a theme you want to base yours on and separate any modifications you make to it into a “child” theme that will inherit everything else from it’s “parent”.
  • Frameworks – Frameworks are themes that have been designed to be used as a starting point or a parent theme. Some have feature rich options pages that allow you to build a theme or site from within the WordPress admin. These really help theme developers to avoid repeating the same code in every theme they make. One caveat to this is that if you’re new to WP, you need to learn all the wordpress specific code as well as any additional code for the theme framework . It complicates the learning curve a bit, but it has long term benefits of speed and ease.

My preferred theme route is using a theme framework. My preferred framework is thematic. Thematic is the ultimate in SEO-ready themes, it is a highly extensible framework which features 13 widget-ready areas, drop-down menus, grid-based layout samples, plugin integration, shortcodes for your footer, and a whole lot more. Thematic as of now is about to get a significant update as well. Resources for thematic include forums, guides, diagrams, tutorials, thematic4you …

Before getting into the design, let’s talk one more fundamental wordpress term: hooks

Hooks are spots in the code that are flagged for us to easily customize how our site or theme functions. To visualize, think about all the thousands of lines of code that gets executed to load a page on a site (yes, there are thousands), and think of it like each line of code is like someone in line at the gracery store checkout . They’d be lined up in order of execution. Hooks are like people in the line that are holding a sign allowing you to cut in line at that precise position to run your own code. There are action hooks and filter hooks in wordpress. Action hooks are for executing your own action at that spot in line, and a filter is about changing something in the line right there. Like if you wanted to insert some ad at the end of every post. You could either add an action that would place it there, filter the post content and add it to the content itself (and you could even filter the content before it goes to the database, or before it’s rendered onto the page). More on action and filter hooks here.

Returning to that added complexity of using a framework, many frameworks will add their own hooks on top of the wordpress hooks. So on top of learning any wordpress hooks you also need to learn the ones specific to your chosen framework where you need to access them. So once you get used to using one framework it may be painful to leave and loose and invested learning in that one. Check these diagrams of thematic structure (blue mandela.com and visualizing.thematic4you.com) including hooks for an visual representation. And the thematic guide to filters and hooks.

Getting from a design in photoshop to an actual WordPress (thematic) child theme while trying not to reinvent the wheel.

The Technical – Actually making the theme

Once you install thematic in your wordpress site, look at the theme directory (/wp-content/themes/thematic/) and you’ll see that thematic comes with a ‘thematicsamplechildtheme’. It’s nice that they thought of this, it gives us a great starting place! We copy that folder, rename it to whatever we want, and place it in the theme directory (sibling to thematic itself). Like so:

thematic child theme directory

The thematicsamplechildtheme has 3 files in it: the style.css, functions.php, readme.txt. I added the screenshot.png file (it will automatically get pulled into the backend as the image of the theme) and made some edits to the stylesheet. Later we’ll add all our styles to the css here, but for now we need to understand that the comment block in the file communicates the details of the theme to wordpress. We need to edit the css file so it reflects our theme properly. The block of text in the comment is formated in a specific way that wordpress will read it and it’s actually pretty self explanitory! All we need to do is update the details. Take special notice of the Template line (it’s what tells WordPress that this theme is a child theme using thematic as the parent), here’s what I’ve done:

[cc lang=”css’]
/*
Theme Name: Corporate Clean : A Thematic Child Theme
Theme URI:
Description: Thematic Child Theme Presentation
Author: Evan Mullins
Author URI: https://circlecube.com/circlecube/
Template: thematic
Version: 1.0
Tags: Thematic
.
Thematic is © Ian Stewart http://themeshaper.com/
Corporate Clean Design by Zsolt Kacso http://kaolti.com/ http://www.behance.net/kaolti/frame/1498151
.
*/
[/cc]

Once we have this in place, we go to the appearance section in our wordpress dashboard and select our theme. Then we can then make our edits to our stylesheet and see them live on our site!

theme chosen for use on site

Before we go opening a can of CSS, let’s look at a couple things and think big picture. We haven’t yet mentioned what this ‘functions.php’ file is. This is the section where we will do any php related to our theme, in other words our hooks! That includes any wordpress or thematic hooks. This samle theme actually has a couple snippets we can uncomment and a sample filter.

Process & Workflow

My purpose in this presentation was never to show you how to slice a photoshop document into web ready images or how to write CSS. I just wanted to help people get more familiar with or started with building themes. I want to talk a little about my process because when I started theming, while I understood the tech (as in css/html) (although I still had and have lots to learn), the process around theming was somewhat of a mystery. I usually follow a loose workflow/cycle when I’m making a site:

  1. Layout – Wireframe, get content areas (widgets) blocked out. Getting the right content in the right places, or creating the right places to put the content.
  2. Structure – Info Archietecture, get the proper post types and think through any needed templates. Getting the right content types. Ideally we should put this code into a theme functionality plugin to separate the functionality from the visual style. Some think it’s best to put that into a plugin so the theme can be changed. But that’s beyond the scope of this presentation, so I’m just going to show you the code to do it and include it in the theme for now.
  3. Style/Design – CSS, using images and styles to get things visual. Getting the right content looking right.
  4. Interactive – JS, making any client-side scripts lively. Getting content interactive.
  5. Population – The plain old and sometimes even boring, data entry.
  6. Rinse and repeat! This is loose and a cycle, I jump through each of these phases numerous times for each element.

Each of these phases contain different tasks, I’ll include some examples and point out some resources. I don’t want to focus on the exact things to do for any and every situation, but talk more about the way to do things. Basically teach to fish, rather than feed you a few fish.

I think I’ll leave that for another day though. This has gotten quite long!

Video via WordPress.tv

Snow via Javascript & Canvas – Tis the Season

After playing with the settings in my experiments I found a few settings I liked and wanted to develop further. The first was snow! An added bonus I was able to work on a project just for the holidays and used much of this code in it! I looked around the web and saw a couple interesting examples of snow, but nothing that stood out to me. I used couple images and pulled them into the canvas in place of the dot (choosing one of 3 flake graphics), and learned how to apply a rotation to that graphic from somewhere online (I think stackoverflow, but now I can’t find it again to link it. The physics settings are hardcoded now and the update function doesn’t check the dot y position against the top of the page, since the snow should all be moving down with the gravity, it could be moved up with it’s floating, but I just wanted it to come down on it’s own. Then to get the rotation we need to save the context state, more to the flake center, rotate it and then move back to the canvas origin, draw the image and restore context. This process sounded complicated and took a bit to get things in the right order and the whole time I was scared it would be too processor intense for a good amount of snowflakes, it seems to do just fine! interactive physics animations via javascript & canvas | snow application example: check it out!

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 150;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;
var gravity = .05;
var friction = .98;
var bounce = -.96;
var wrap = true;
var float = true;

var imgs = new Array();
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
img1.src = “snowflake_1.png”;
img2.src = “snowflake_2.png”;
img3.src = “snowflake_3.png”;
imgs[0] = img1;
imgs[1] = img2;
imgs[2] = img3;
var this_dot = {};
for (var i=0; i < total_dots; i++){ createDot(); } function createDot(x, y, r, vx, vy){ var this_dot = { x: typeof(x) != 'undefined' ? x : Math.random()*canvas.width, y: typeof(y) != 'undefined' ? y : Math.random()*-canvas.height, radius: typeof(r) != 'undefined' ? r : 25, scale: Math.floor(10 + (1+50-10)*Math.random()), vx: typeof(vx) != 'undefined' ? vx : Math.random()*3-1, vy: typeof(vy) != 'undefined' ? vy : Math.random()*3, //this will pick a digit 1, 2 or 3 and set it as the src value, this could also be a Math.floor(Math.random()*3)+1 to really be random src: (dots.length % 3) + 1, r: 0, vr: 0 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { createDot(event.pageX - this.offsetLeft-25, event.pageY - this.offsetTop-25); }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; if (float){ this_dot.vx += Math.random() - .5; this_dot.vy += Math.random() - .5; this_dot.vr += Math.random()*.01 - .005; } this_dot.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; this_dot.r += this_dot.vr; if (this_dot.x > canvas.width + this_dot.radius){
this_dot.x -= canvas.width + this_dot.radius*2;
this_dot.vr = 0;
}
else if(this_dot.x < 0 - this_dot.radius){ this_dot.x += canvas.width + this_dot.radius*2; this_dot.vr = 0; } if (this_dot.y > canvas.height + this_dot.radius){
this_dot.y -= canvas.height + this_dot.radius*2;
this_dot.vr = 0;
}

}
}
}
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
for (var i=0; i < dots.length; i++){ var src = img1; if (dots[i].src == 1){ } else if (dots[i].src == 2){ src = img2; } else { src = img3; } context.save(); context.translate(dots[i].x+dots[i].scale/2, dots[i].y+dots[i].scale/2); context.rotate(dots[i].r); context.translate(-dots[i].x-dots[i].scale/2, -dots[i].y-dots[i].scale/2); context.drawImage(src, dots[i].x, dots[i].y, dots[i].scale, dots[i].scale); context.restore(); } } setInterval(function() { update(); draw(); }, 1000/fps); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Microsoft Touch Mouse and The Art of Touch | Giveaway

Microsoft has a new line of TouchMouse. They have a campaign to cooinside with it called the Art of Touch and have invited a few artists to participate and more to drive interest with free shwag! Basically that boils down to me having a [amazon_link id=”B004HYGU18″ target=”_blank” ]Microsoft Touch Mouse[/amazon_link] to give away! So go play with the app and link a comment to your art. I’ll randomly select someone for the award as a christmas present! Be sure to comment with an email address you’ll reply to.

[amazon_image id=”B004HYGU18″ link=”true” target=”_blank” size=”medium” ]Microsoft Touch Mouse[/amazon_image]

I played with the drawing app, and while it’s not totally generative, it does add a sense of randomness to it. It’s fun in that it tried to incorporate a few different styles of artists, including one of my favorites, Erik Natzke. Here’s what Erik had to say:

Along with the custom brush that I designed for them, there are an assortment of brush styles they’ve designed to help hone in on your artistic flair that you can share, print & even compete to win some prizes. The link below will allow you to vote on the one I just made. I’m curious what other people will make.

And here’s what I came up with in a couple minutes:

Comment below with a link to your art to be entered to win a new [amazon_link id=”B004HYGU18″ target=”_blank” ]Microsoft Touch Mouse[/amazon_link] this Christmas.

Interactive Physics Animations Javascript Canvas 17

I’m really enjoying giving a control panel of sorts to the end user and letting them control the physics rules of their canvas. Let’s add more motion to it by applying a jitter to the velocity of each dot. This is similar to earlier, when we first started animating by applying a random number to the coordinates, but now we’ll apply a (smaller) random number to the velocity. This will be much smoother and will give a sense of real life to the dots. Straight lines and trajectories is always theoretical and hypothetical, but to make things look more real, sometimes we have to break the clean, straight lines. This will be another checkbox to control the float. I’m really enjoying the fact that the more properties we add to our controls we get exponentially more possible configurations. Perhaps we should even give a slider to control the strength of gravity…
interactive physics animations via javascript & canvas | 17.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 10;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;
var gravity = 0;
var friction = .98;
var bounce = -.96;
var wrap = false;
var float = true;

var this_dot = {};
for (var i=0; i < total_dots; i++){ createDot(); } function createDot(x, y, r, vx, vy){ var this_dot = { x: typeof(x) != 'undefined' ? x : Math.random()*canvas.width, y: typeof(y) != 'undefined' ? y : Math.random()*canvas.height, radius: typeof(r) != 'undefined' ? r : Math.random()*20+10, vx: typeof(vx) != 'undefined' ? vx : Math.random()*30-10, vy: typeof(vy) != 'undefined' ? vy : Math.random()*30-10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } //none clicked if (!drag) { createDot(event.pageX - this.offsetLeft, event.pageY - this.offsetTop); } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].old_x = dots[drag_i].x; dots[drag_i].old_y = dots[drag_i].y; dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; dots[drag_i].vx = dots[drag_i].x - dots[drag_i].old_x; dots[drag_i].vy = dots[drag_i].y - dots[drag_i].old_y; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; if (float){ this_dot.vx += Math.random() - .5; this_dot.vy += Math.random() - .5; } this_dot.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; if (wrap){ if (this_dot.x > canvas.width + this_dot.radius){
this_dot.x -= canvas.width + this_dot.radius*2;
}
else if(this_dot.x < 0 - this_dot.radius){ this_dot.x += canvas.width + this_dot.radius*2; } if (this_dot.y > canvas.height + this_dot.radius){
this_dot.y -= canvas.height + this_dot.radius*2;
}
else if(this_dot.y < 0 - this_dot.radius){ this_dot.y += canvas.height + this_dot.radius*2; } } else if (!wrap) { if (this_dot.x > canvas.width – this_dot.radius){
this_dot.x = canvas.width – this_dot.radius;
this_dot.vx = this_dot.vx * bounce;
}
else if(this_dot.x < 0 + this_dot.radius){ this_dot.x = this_dot.radius; this_dot.vx = this_dot.vx * bounce; } if (this_dot.y > canvas.height – this_dot.radius){
this_dot.y = canvas.height – this_dot.radius;
this_dot.vy = this_dot.vy * bounce;
}
else if(this_dot.y < 0 + this_dot.radius){ this_dot.y = this_dot.radius; this_dot.vy = this_dot.vy * bounce; } } } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); $("#wrap").click(function(){ if($("#wrap").is(':checked')){ wrap = true; } else{ wrap = false; } }); $("#float").click(function(){ if($("#float").is(':checked')){ float = true; } else{ float = false; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 16

I always want to give the end user (at least some) control of how they view and interact with data. Earlier we gave users control over gravity. Here let’s give them control over the canvas edges. Rather than having our dots bounce on the edges of the canvas, lets have them wrap across to the other side. Like in the asteroids game the ship can fly to the edge of the screen and see space wrap them back to the other side. We’ll set this up as a control exposed to the user much like gravity. Let’s call it wrap and use a boolean value to store the setting. We’ll need to add another block of conditionals for this case where we have the set already with the bouncing. I took some care with the values so that the dots leave the canvas before they make the hyper-jump to the other side. Otherwise you’d see the magic. interactive physics animations via javascript & canvas | 16.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 10;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;
var gravity = 0;
var friction = .98;
var bounce = -.96;
var wrap = true;

var this_dot = {};
for (var i=0; i < total_dots; i++){ createDot(); } function createDot(x, y, r, vx, vy){ var this_dot = { x: typeof(x) != 'undefined' ? x : Math.random()*canvas.width, y: typeof(y) != 'undefined' ? y : Math.random()*canvas.height, radius: typeof(r) != 'undefined' ? r : Math.random()*20+10, vx: typeof(vx) != 'undefined' ? vx : Math.random()*30-10, vy: typeof(vy) != 'undefined' ? vy : Math.random()*30-10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } //none clicked if (!drag) { createDot(event.pageX - this.offsetLeft, event.pageY - this.offsetTop); } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].old_x = dots[drag_i].x; dots[drag_i].old_y = dots[drag_i].y; dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; dots[drag_i].vx = dots[drag_i].x - dots[drag_i].old_x; dots[drag_i].vy = dots[drag_i].y - dots[drag_i].old_y; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; if (wrap){ if (this_dot.x > canvas.width + this_dot.radius){
this_dot.x -= canvas.width + this_dot.radius*2;
}
else if(this_dot.x < 0 - this_dot.radius){ this_dot.x += canvas.width + this_dot.radius*2; } if (this_dot.y > canvas.height + this_dot.radius){
this_dot.y -= canvas.height + this_dot.radius*2;
}
else if(this_dot.y < 0 - this_dot.radius){ this_dot.y += canvas.height + this_dot.radius*2; } } else if (!wrap) { if (this_dot.x > canvas.width – this_dot.radius){
this_dot.x = canvas.width – this_dot.radius;
this_dot.vx = this_dot.vx * bounce;
}
else if(this_dot.x < 0 + this_dot.radius){ this_dot.x = this_dot.radius; this_dot.vx = this_dot.vx * bounce; } if (this_dot.y > canvas.height – this_dot.radius){
this_dot.y = canvas.height – this_dot.radius;
this_dot.vy = this_dot.vy * bounce;
}
else if(this_dot.y < 0 + this_dot.radius){ this_dot.y = this_dot.radius; this_dot.vy = this_dot.vy * bounce; } } } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); $("#wrap").click(function(){ if($("#wrap").is(':checked')){ wrap = true; } else{ wrap = false; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.

Interactive Physics Animations Javascript Canvas 15

Earlier we worked on making all the dots draggable, but what’s better than simply dragging dots? Let’s set up a way to throw the dots! Now as we drag it we record the positions and use that to calculate a new velocity. Then when a dot is dropped, it will have a trajectory to follow that matches the path and speed it was dragged. This iteration only looks at the current frame and the previous frame, but a better solution may be to average the previous few positions to get a better feel. I’ve noticed that (with a mouse especially) people tend to stop dragging just before they mouseup, so this kills any velocity the dot receives during the drag. Enjoy throwing the dots around the canvas! interactive physics animations via javascript & canvas | 15.

[cc lang=”javascript”]
$(function () {
var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
var total_dots = 10;
var fps = 24;

canvas = $(“#canvas”)[0];
context = canvas.getContext(“2d”);
var dots = new Array();
var drag_i = -1;
var gravity = 2;
var friction = .98;
var bounce = -.96;

var this_dot = {};
for (var i=0; i < total_dots; i++){ createDot(); } function createDot(x, y, r, vx, vy){ var this_dot = { x: typeof(x) != 'undefined' ? x : Math.random()*canvas.width, y: typeof(y) != 'undefined' ? y : Math.random()*canvas.height, radius: typeof(r) != 'undefined' ? r : Math.random()*20+10, vx: typeof(vx) != 'undefined' ? vx : Math.random()*30-10, vy: typeof(vy) != 'undefined' ? vy : Math.random()*30-10 }; dots.push(this_dot); } draw(); $("#canvas").mousedown(function (event) { var dx, dy, dist; for (var i=0; i < dots.length; i++){ dx = event.pageX - this.offsetLeft - dots[i].x; dy = event.pageY - this.offsetTop - dots[i].y; dist = Math.sqrt(dx * dx + dy * dy); if(dist < radius) { drag = true; drag_i = i clickX = dx; clickY = dy; continue; } } //none clicked if (!drag) { createDot(event.pageX - this.offsetLeft, event.pageY - this.offsetTop); } }); $("#canvas").mouseup(function (event) { drag = false; drag_i = -1; }); $("#canvas").mousemove(function (event) { if(drag) { dots[drag_i].old_x = dots[drag_i].x; dots[drag_i].old_y = dots[drag_i].y; dots[drag_i].x = event.pageX - this.offsetLeft - clickX; dots[drag_i].y = event.pageY - this.offsetTop - clickY; dots[drag_i].vx = dots[drag_i].x - dots[drag_i].old_x; dots[drag_i].vy = dots[drag_i].y - dots[drag_i].old_y; draw(); } }); function update(){ for (var i=0; i < dots.length; i++){ if (drag_i != i){ var this_dot = dots[i]; this_dot.vx *= friction; this_dot.vy = this_dot.vy * friction + gravity; this_dot.x += this_dot.vx; this_dot.y += this_dot.vy; if (this_dot.x > canvas.width – this_dot.radius){
this_dot.x = canvas.width – this_dot.radius;
this_dot.vx = this_dot.vx * bounce;
}
else if(this_dot.x < 0 + this_dot.radius){ this_dot.x = this_dot.radius; this_dot.vx = this_dot.vx * bounce; } if (this_dot.y > canvas.height – this_dot.radius){
this_dot.y = canvas.height – this_dot.radius;
this_dot.vy = this_dot.vy * bounce;
}
else if(this_dot.y < 0 + this_dot.radius){ this_dot.y = this_dot.radius; this_dot.vy = this_dot.vy * bounce; } } } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i=0; i < dots.length; i++){ context.beginPath(); context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false); context.fill(); context.closePath(); } } setInterval(function() { update(); draw(); }, 1000/fps);$("#gravity").click(function(){ if($("#gravity").is(':checked')){ gravity = 2; } else{ gravity = 0; } }); }); [/cc]Follow the whole Interactive Physics Animations via Javascript & Canvas series.