When you did the following, it gets the div element hosting kineticjs...it doesn't get a canvas.
canvas = document.getElementById('container');
That's why your call to getContext
fails.
[Edited to include an example of magnification using Kinetic's custom Shape]
We can use the Kinetic Shape object which is designed to allow us to do custom drawing.
We can custom draw anything in the drawFunc
function because we have access to the canvas context.
drawfunc
will be called every time the custom Shape needs to be redrawn.
Here is the Kinetic custom Shape object in outline form:
zoomer = new Kinetic.Shape({
// The drawFunc lets us do custom drawings because are given the canvas
drawFunc: function(canvas) {
// We can use the canvas context
var ctx = canvas.getContext();
ctx.beginPath();
// now we make any custom drawings
// *** put custom drawing code here ***
// but we must finish with this Kinetic-specific fillStroke(this)
// to render the drawing (not optional!)
canvas.fillStroke(this);
}
});
Now for some zoomer specifics.
First, use a temporary html canvas to create a copy of the image at ½ resolution:
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
canvas.width=image.width/2;
canvas.height=image.height/2;
ctx.drawImage(image,
0,0,image.width,image.height,
0,0,image.width/2,image.height/2);
In the drawFunc
function of the Shape, draw a rectangle containing the half-resolution image.
Notice that drawFunc
must conclude with canvas.fillStroke(this)
canvas.fillStroke(this)
is a KineticJS specific command that renders the drawings and it is required.
zoomer = new Kinetic.Shape({
drawFunc: function(canvas) {
var ctx = canvas.getContext();
ctx.beginPath();
ctx.rect( 0,0, image.width/2, image.height/2 );
ctx.drawImage(halfCanvas,0,0);
canvas.fillStroke(this);
},
});
If the mouse is down, also draw the zoom viewer with a cropped portion of the full size image.
if(this.MouseIsDown){
ctx.rect(mouseX,mouseY,viewerSize,viewerSize);
ctx.drawImage(image,
mouseX, mouseY, viewerSize, viewerSize,
this.mouseX,this.mouseY, viewerSize, viewerSize);
}
That’s it...See the code below for some fine-points and styling.
Here’s a Fiddle that must be viewed in Chrome or Mozilla (IE=CORS exception): http://jsfiddle.net/m1erickson/dMr8g/
Here is example code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.3.min.js"></script>
<style>
body{ background-color: ivory; padding:30px; }
#container{ width:200px; height:200px; border:1px solid red;}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 200,
height: 200
});
var layer = new Kinetic.Layer();
stage.add(layer);
// create an image to zoom
var zoomImage=new Image();
var halfCanvas=document.createElement("canvas");
var halfCtx=halfCanvas.getContext("2d");
var width;
var height;
var halfWidth;
var halfHeight;
var zoomer;
var zSize=60;
var zOffset=zSize/2;
zoomImage.onload=function(){
width=zoomImage.width;
height=zoomImage.height;
halfWidth=width/2;
halfHeight=height/2;
halfCanvas.width=halfWidth;
halfCanvas.height=halfHeight;
halfCtx.drawImage(zoomImage,
0,0,width,height,
0,0,halfWidth,halfHeight);
addZoomer();
}
zoomImage.src="yourImage.png";
function addZoomer(image){
zoomer = new Kinetic.Shape({
drawFunc: function(canvas) {
var ctx = canvas.getContext();
ctx.beginPath();
ctx.rect(zOffset,zOffset,halfWidth,halfHeight);
ctx.drawImage(halfCanvas,zOffset,zOffset);
if(this.MouseIsDown){
var ix=this.mouseX*2-zOffset;
var iy=this.mouseY*2-zOffset;
// adjust if zoom is off the image
if(ix<0){ ix=0; };
if(ix>width){ ix=width-zSize; };
if(iy<0){ iy=0; };
if(iy>height){ iy=height-zSize; };
ctx.rect(this.mouseX,this.mouseY,zSize,zSize);
ctx.drawImage(zoomImage,
ix,iy,zSize,zSize,
this.mouseX,this.mouseY,zSize,zSize);
}
canvas.fillStroke(this);
},
x:0,
y:0,
width:halfWidth,
height:halfHeight,
id: "zoomer",
stroke:"blue",
strokeWidth:2
});
zoomer.zoomImage=
zoomer.MouseIsDown=false;
zoomer.mouseX=0;
zoomer.mouseY=0;
zoomer.on('mousedown', function(e) {
var mouseXY=stage.getMousePosition();
this.mouseX=mouseXY.x-zOffset;
this.mouseY=mouseXY.y-zOffset;
this.MouseIsDown=true;
layer.draw();
});
zoomer.on('mouseup', function(e) {
this.MouseIsDown=false;
layer.draw();
});
layer.add(zoomer);
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>