Dit is deel twee van een serie van drie blogs over het HTML 5 Canvas. In het eerste deel hebben we gekeken naar het canvas element. Wat doet het en hoe kunnen we tekenen op het canvas door middel van Javascript. In dit tweede deel gaan we kijken hoe de context van het canvas kunnen manipuleren. Tevens kijken we naar het werken met afbeeldingen en video's.

Dit is deel twee van een serie van drie blogs over het HTML 5 Canvas. In het eerste deel hebben we gekeken naar het canvas element. Wat doet het en hoe kunnen we tekenen op het canvas door middel van Javascript. In dit tweede deel gaan we kijken hoe de context van het canvas kunnen manipuleren. Tevens kijken we naar het werken met afbeeldingen en video's.
Context instellingen
Naast het tekenen van vormen zijn er ook een aantal functies om de context zelf te manipuleren, zoals roteren, vervormen, schalen, transparantie en verplaatsen van het nulpunt. Het is mogelijk om de huidige instellingen voor de context te bewaren en later naar deze staat terug te keren door middel van de save() en restore() methodes. Dit kan handig zijn als we voor het tekenen van een bepaald object een functie maken. Door het aanroepen van deze functie kunnen we dan het zelfde object vaker tekenen, maar dan op verschillende posities of verschillende instellingen van de context.
In onderstaand voorbeeld heb ik een functie aangemaakt voor het tekenen van een object, in dit geval een blauw vierkantje. Deze functie roep ik 10 keer aan terwijl de context semitransparant is en telkens iets verder geroteerd wordt.
function initialize() {
    var canv = document.getElementById('voorbeeld');
    var ctx = canv.getContext('2d');
    ctx.save();
    ctx.globalAlpha = 0.1; // teken voortaan met 10% alpha (transparantie)
    ctx.translate(250, 250);  // zet het 0 punt in het midden van het canvas
    for (var i = 0; i < 10; i++)
    {
        // 1 rotatie is 2*PI, dus per loop 1/10 daarvan verder roteren
        ctx.rotate((2* Math.PI)*(1/10));
        drawRectangle(ctx);
    }
    ctx.restore();
}
function drawRectangle(ctx) {
    // blauw vierkant
    ctx.fillStyle = 'rgb(0, 0, 100)';
    ctx.fillRect(0, 0, 150, 150);
}

De context en graphics
De laatste context instelling die ik genoemd wil hebben is de dropshadow. Het is mogelijk om aan te geven welke kleur en welke hoek de shadow heeft en hoe scherp of diffuus de schaduw is.
ctx.shadowColor = 'rgba(0,0,0,0.8)';  // zwart met 80% alpha
ctx.shadowOffsetX = 5; // schaduw x-richting: 5px naar links
ctx.shadowOffsetY = 3; // schaduw y-richting: 3px naar beneden
ctx.shadowBlur = 5; // vervaagt over 5px

De context en graphics
Afbeeldingen
Naast het tekenen van vormen is het ook mogelijk om afbeeldingen te gebruiken. Het is daarbij belangrijk om ervoor te zorgen dat de afbeelding ingeladen is voordat deze door de context gebruikt wordt. Mocht dit vergeten worden, dan zal er namelijk niets getekend worden. Je kunt bijvoorbeeld in de onload eventhandler van de afbeelding de code schrijven die de afbeelding op het canvas tekent. Uiteraard kunnen we afbeeldingen ook gebruiken in combinatie met de voorgaande tekenfunctionaliteiten.
In het onderstaande voorbeeld tekenen we een foto met daar omheen een grijze rechthoek. Vervolgens wordt de y-schaal van de context naar -1 gezet (of tewel gespiegeld) en tekenen we nogmaals de foto en rechthoek. Door hierna een verloop (gradiënt) toe te voegen, krijg je een soort "wet floor" effect.
function initialize() {
    var canvas = document.getElementById('canv');
    var context = canvas.getContext('2d');
    var image = new Image();
    image.src = "images/pict1.jpg";
    // use image only after it has loaded!
    image.onload = function () {
        context.save();
        context.translate(20, 20);
        drawPhoto(context, image); // draw photo
        context.translate(0, 418);
        context.scale(1, -1); //  mirror context
        drawPhoto(context, image); // draw photo mirrored
        // add gradient on the wet floor
        var grad = context.createLinearGradient(0, 0, 0, 212);
        grad.addColorStop(0.2, 'rgba(255,255,255,1)');
        grad.addColorStop(1, 'rgba(255,255,255,0.4)');
        context.fillStyle = grad;
        context.fillRect(-3, -3, 312, 212);
        context.fill();               
        context.restore();
    }
}
function drawPhoto(context, img) {
    context.strokeStyle = '#444444';
    context.lineWidth = 6;
    context.strokeRect(0, 0, 306, 206);
    context.drawImage(img, 3, 3, 300, 200);
}

De context en graphics
Canvas in combinatie met Video
De drawImage() functie van de context wordt dus gebruikt om afbeeldingen op het Canvas te tekenen. Als eerste parameter geven we de afbeelding op die we willen gebruiken. Het is echter ook mogelijk om in plaats van een afbeelding, hier een HTML5 video-element op te geven. De context zal dan een soort screenshot van de video tekenen. Aangezien het canvas uit pixels bestaat, kunnen we het screenshot van de video op pixelniveau aanpassen. Denk aan het het omzetten naar grijstinten of het vervangen van een bepaalde kleur (green-screen).
Ik heb eerder aangegeven dat het Canvas in staat is om in hoog tempo te tekenen. Door de video bijvoorbeeld 25 keer per seconde op het Canvas te tekenen (al dan niet met een bewerking) krijg je optisch weer een video. Hierdoor is het dus mogelijk om realtime, clientside, een video te bewerken of effecten toe te voegen.
De context en graphics
In dit artikel ga ik niet verder in op het HTML5 video-element, maar voor meer informatie kun je terecht op mijn HTML5 video blog.