HTML5 Canvas and PHP Programming Club IIT Kanpur

Preview:

Citation preview

HTML5 Canvas and PHP

Programming Club IIT Kanpur

The canvas tag

•Similar to the <div>, <a>, or <table> tag, with the exception that its contents are rendered with JavaScript

•The canvas context is an object with properties and methods that you can use to render graphics inside the canvas element.  The context can be 2d or webgl (3d).

Canvas Template<body>  <canvas id="myCanvas" width="578" height="200"></canvas>  <script>    var canvas = document.getElementById('myCanvas');    var context = canvas.getContext('2d');

    // do stuff here  </script></body>

Line

• use the beginPath(), moveTo(), lineTo(), and stroke() methods

• beginPath() - to declare that we are about to draw a new path

• moveTo() - to position the context point (i.e. Starting point),

• lineTo() -  to draw a straight line from the starting position to a new position

• stroke() - to make the line visible i.e fill color in the line

Line<body>    <canvas id="myCanvas" width="578" height="200"></canvas>    <script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      context.beginPath();      context.moveTo(100, 150);      context.lineTo(450, 50);      context.stroke();    </script>  </body>

Properties of Line

• Line Width - context.lineWidth = 15; Must be set before stroke() function

• Line Color – context.strokeStyle = '#ff0000';

• Line Cap – Can be round, square or butt. Specified by context.lineCap = 'round';

Arc

• Arcs are defined by a center point, a radius, a starting angle, an ending angle, and the drawing direction (either clockwise or anticlockwise).

• Angle should be in radians

• Arcs can be styled with the lineWidth, strokeStyle, and lineCap properties

Arc<body>    <canvas id="myCanvas" width="578" height="250"></canvas>    <script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');      var x = canvas.width / 2;      var y = canvas.height / 2;      var radius = 75;      var startAngle = 1.1 * Math.PI;      var endAngle = 1.9 * Math.PI;      var counterClockwise = false;

      context.beginPath();      context.arc(x, y, radius, startAngle, endAngle, counterClockwise);      context.lineWidth = 15;      context.strokeStyle = 'black';      context.stroke();    </script>  </body>

Quadratic Curve

• Use the quadraticCurveTo() method

• Quadratic curves can be styled with the lineWidth, strokeStyle, and lineCap properties

Quadratic Curve

• Context Point is soecified by the context.moveTo() function

• QuadraticCurveTo() function takes 4 arguments-

•     the x co-ordinate of the control point

•     the y co-ordinate of the control point

•     the x co-ordinate of the end point

•     the y co-ordinate of the end point

Quadratic Curve

<body>    <canvas id="myCanvas" width="578" height="200"></canvas>    <script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      context.beginPat1h();      context.moveTo(188, 150);      context.quadraticCurveTo(288, 0, 388, 150);      context.lineWidth = 10;      context.strokeStyle = 'black';      context.stroke();    </script>  </body>

Path

• To create a path with HTML5 Canvas, we can connect multiple subpaths.  The ending point of each new subpath becomes the new context point.

•   We can use the lineTo(), arcTo(), quadraticCurveTo(), and bezierCurveTo() methods to construct each subpath which makes up our path.  We can also use the beginPath() method each time we want to start drawing a new path.

Pathcanvas id="myCanvas" width="578" height="200"></canvas>    <script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      context.beginPath();      context.moveTo(100, 20);      // line 1      context.lineTo(200, 160);      // quadratic curve      context.quadraticCurveTo(230, 200, 250, 120);      // bezier curve      context.bezierCurveTo(290, -40, 300, 200, 400, 150);      // line 2      context.lineTo(500, 90);

      context.lineWidth = 5;      context.strokeStyle = 'blue';      context.stroke();

    </script>

Joining Lines

•To set the line join style of an HTML5 Canvas path, we can set the lineJoin context property

•Paths can have one of three line joins: miter, round, or bevel

•Unless otherwise specified, the HTML5 Canvas line join property is defaulted with the miter style

Joining Lines

<script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      // set line width for all lines      context.lineWidth = 25;

// round line join (middle)      context.beginPath();      context.moveTo(239, 150);      context.lineTo(289, 50);      context.lineTo(339, 150);      context.lineJoin = 'round';      context.stroke(); </script> 

Rounded Corners

• we  use the arcTo() method which is defined by a control point, an ending point, and a radius.

Rounded Corners<script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');      var rectWidth = 200;      var rectHeight = 100;      var rectX = 189;      var rectY = 50;      var cornerRadius = 50;

      context.beginPath();      context.moveTo(rectX, rectY);      context.lineTo(rectX + rectWidth - cornerRadius, rectY);      context.arcTo(rectX + rectWidth, rectY, rectX + rectWidth, rectY + cornerRadius, cornerRadius);      context.lineTo(rectX + rectWidth, rectY + rectHeight);      context.lineWidth = 5;      context.stroke();    </script>

Custom Shape

•To create a custom shape with HTML5 Canvas, we can create a path and then close it using the closePath() method.

•We can use the lineTo(), arcTo(), quadraticCurveTo(), or bezierCurveTo() methods to construct each subpath which makes up our shape

Custom Path<script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      // begin custom shape      context.beginPath();      context.moveTo(170, 80);      context.bezierCurveTo(130, 100, 130, 150, 230, 150);      context.bezierCurveTo(250, 180, 320, 180, 340, 150);      context.bezierCurveTo(420, 150, 420, 120, 390, 100);      context.bezierCurveTo(430, 40, 370, 30, 340, 50);      context.bezierCurveTo(320, 5, 250, 20, 250, 50);      context.bezierCurveTo(200, 5, 150, 20, 170, 80);

      // complete custom shape      context.closePath();      context.lineWidth = 5;      context.strokeStyle = 'blue';      context.stroke();

Rectangle

•we can use the rect() method rather than constructing the shape with 4 connecting lines.

• rectangle is positioned with x and y parameters, and is sized with width and height parameters.

•The rectangle is positioned about its top left corner.

Rectangle

<script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      context.beginPath();      context.rect(188, 50, 200, 100);      context.fillStyle = 'yellow';      context.fill();      context.lineWidth = 7;      context.strokeStyle = 'black';      context.stroke();    </script>

Circle

We  create a full arc using the arc() method by defining the starting angle as 0 and the ending angle as 2 * PI

Color Filling

•To fill an HTML5 Canvas shape with a solid color, we can set the fillStyle property to a color.

• then we can use the fill() method to fill the shape.

•When setting both the fill and stroke for a shape, make sure that you use fill() before stroke(). Otherwise, the fill will overlap half of the stroke

Filling Color• <script>

      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');      // begin custom shape      context.beginPath();      context.moveTo(170, 80);      context.bezierCurveTo(130, 100, 130, 150, 230, 150);      context.bezierCurveTo(250, 180, 320, 180, 340, 150);      context.bezierCurveTo(420, 150, 420, 120, 390, 100);      context.bezierCurveTo(430, 40, 370, 30, 340, 50);      context.bezierCurveTo(320, 5, 250, 20, 250, 50);      context.bezierCurveTo(200, 5, 150, 20, 170, 80);      // complete custom shape      context.closePath();      context.lineWidth = 5;      context.fillStyle = '#8ED6FF';      context.fill();      context.strokeStyle = 'blue';      context.stroke();    </script>

Drawing Image

• To draw an image using HTML5 Canvas, we use the drawImage() method which requires an image object and a destination point.

• The destination point defines the top left corner of the image relative to the top left corner of the canvas.

•       var imageObj = new Image();

      imageObj.onload = function() {        context.drawImage(imageObj, 69, 50);      };      imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';

Image Size

• we add two additional arguments to the drawImage() method, width and height

•       var width = 200;      var height = 137;      var imageObj = new Image();

      imageObj.onload = function() {        context.drawImage(imageObj, x, y, width, height);      };

Crop an Image• We add six additional arguments to the drawImage() method,

sourceX, sourceY, sourceWidth, sourceHeight, destWidth and destHeight.

Text

• To draw text using HTML5 Canvas, we can use the font property and the fillText() method of the canvas context.

• To set the font, size, and style of HTML5 Canvas text, we set the font property of the canvas context to a string containing the font style, size, and family, delimited by spaces.

• Once the font property has been set, we can draw the text with the fillText() method, which requires a string and an x and y position

Text

<script>      var canvas = document.getElementById('myCanvas');      var context = canvas.getContext('2d');

      context.font = 'italic 40pt Calibri';      context.fillText('Hello World!', 150, 100);    </script>

Properties Of Text

• TO change text color, set context.fillStyle = "color"

• TO change stroke color, set  context.strokeStyle = "color"

• To align text, use context.textAlign = "center". can be set to start, end, left, center, or right.

• When it's set to start and the document direction is ltr (left to right), or when it's set to end and the document direction is rtl (right to left).

Snake GAME

• Let's make simple snake game using the tools we have learnt.

HTML

<html><canvas id="canvas" width="450" height="450"></canvas>

</html>

Initializing the canvas

var canvas = document.getElementById('canvas');

context = canvas.getContext("2d");

var w = canvas.width();var h = canvas.height();

Painting the canvas

context.fillStyle= "white";context.fillRect(0   , 0, w, h);context.strokeStyle    = "black";

context.strokeRect(0, 0, w, h);

Creating the snake

create_snake();    function create_snake()    {        var length = 5; //Length of the snake        snake_array = []; //Empty array to start with        for(var i = length-1; i>=0; i--)        {            //This will create a horizontal snake starting from the top left            snake_array.push({x: i, y:0});        }    }

Painting the snakevar cw = 10;//cell width

function paint()    {        for(var i = 0; i < snake_array.length; i++)        {            var c = snake_array[i];            //Lets paint 10px wide cells          context.fillStyle  = "blue";          context.fillRect(c.x*cw  , c.y*cw, cw, cw);          context.strokeStyle  = "white";          context.strokeRect(c.x*cw  , c.y*cw, cw, cw);        }    }    

Moving the snake

game_loop = setInterval(paint, 60);

//put the following lines inside the paint function

        //Pop out the tail cell and place it infront of the head cell        var nx = snake_array[0].x;        var ny = snake_array[0].y;        //These were the position of the head cell.        //We will increment it to get the new head position                nx++;                var tail = snake_array.pop(); //pops out the last cell        tail.x = nx;        snake_array.unshift(tail); //puts back the tail as the first cell

Leaving a trail

After every 60ms, paint() function will create new rectangles but not delete the previous ones. This will leave a trail of the movement of the snake.

To fix it, we paint the background of the canvas inside the paint() function.

Direction Based Movement

var d = "right"; //default direction

//add the following lines in the paint functionif(d == "right") nx++;        else if(d == "left") nx--;        else if(d == "up") ny--;        else if(d == "down") ny++;

Keyboard Controls

document.onkeydown = function(e){        var key = e.which;         if(key == "37" && d != "right ") d = "left";        else if(key == "38" && d != "down ") d= " up";        else if(key == "39" && d != "left ") d= " right";        else if(key == "40" && d != "up") d= " down";    };

Game init function

function init()    {        d = "right"; //default direction        create_snake();        create_food();                 game_loop = setInterval(paint, 60);    }

Game Over Condition

if(nx == -1 || nx = w/cw || ny == -1 || ny = h/cw)        {            //restart game            init();            return;        }

Lets Create food now

function create_food()    {        food = {            x: Math.random()*(w-cw)/cw,             y: Math.random()*(h-cw)/cw,         };        //This will create a cell with x/y between 0-44        //Because there are 45(450/10) positions accross the rows and columns    }

A function to paint cells

function paint_cell(x, y)    {        context.fillStyle= "blue";        contetx.fillRect(x*cw, y*cw, cw, cw);        context.strokeStyle= "white";        context.strokeRect(x*cw, y*cw, cw, cw);    }

//Now even while painting snake, we can use this function

Paint food

//inside the paint function

var food;

create_food;

paint_cell(food.x, food.y)

Eating food//If the new head position matches with that of the food,        //Create a new head instead of moving the tail        if(nx == food.x && ny == food.y)        {            var tail = {x: nx, y: ny};            //Create new food            create_food();        }        else        {            var tail = snake_array.pop(); //pops out the last cell            tail.x = nx; tail.y = ny;        }

Checking Body Collision

function check_collision(x, y, array)    {        //This function will check if the provided x/y coordinates exist        //in an array of cells or not        for(var i = 0; i < array.length; i++)        {            if(array[i].x == x && array[i].y == y)             return true;        }        return false;    }

Checking Collision

Addone more condition for game over in the paint function.-

if(nx == -1 || nx == w/cw || ny == -1 || ny == h/cw || check_collision(nx, ny, snake_array ))        {            //restart game            init();            return;        }

And we are done!

Congratulations on Making Your first game. Simple, wasn't it?