How to draw in web 2.0? - html

I heard that drawing abilities will be supported by Web 2.0
Tried to find something in Internet about, nothing really clear. Could you please point me into something that allows (or will allow in future) to draw in HTML?
For example: I want to have ability draw few hexagons in different color on the page.
Thanks.
P.S. Sorry if question is a little bit "stupid", but I can't make it more smart.

A quick exemple of what you want to do:
<html>
<head>
<title>Hexagon canvas tutorial</title>
<script type="text/javascript">
function draw(){
//first let's get canvas HTML Element to draw something on it
var canvas = document.getElementById('tutorial');
//then let's see if the browser supports canvas element
if (canvas.getContext){
var ctx = canvas.getContext('2d');
//Pick Hexagon color, this one will be blue
ctx.fillStyle = "rgb(0, 0, 255)";
//let's start a path
ctx.beginPath();
//move cursor to position x=10 and y=60, and move it around to create an hexagon
ctx.moveTo(10,60);
ctx.lineTo(40,100);
ctx.lineTo(80,100);
ctx.lineTo(110,60);
ctx.lineTo(80,20);
ctx.lineTo(40,20);
//fill it and you got your first Hexagon
ctx.fill();
//This one will be green, but we will draw it like the first one
ctx.fillStyle = "rgb(0, 255, 0)";
ctx.beginPath();
ctx.moveTo(110,160);
ctx.lineTo(140,200);
ctx.lineTo(180,200);
ctx.lineTo(210,160);
ctx.lineTo(180,120);
ctx.lineTo(140,120);
ctx.fill();
}
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="draw();">
<canvas id="tutorial" width="300" height="300"></canvas>
</body>
</html>

What you're talking about is most likely the HTML5 Canvas element

I suspect you've been hearing about the Canvas Element. You can get started with it here: http://en.wikipedia.org/wiki/Canvas_element
Good luck!

Related

Javascript KineticJS Firefox Issue

Im trying to do a composite operation on layers using KineticJS.
Everything works fine in Chrome, but nothing shows for firefox, or IE10
The code runs through without any errors.
You can see the issue here:
http://clients.lilodesign.com/Lilo/Kinetic/
Chrome you should see a circle with a partial bit of the standard MS Blue Trees image showing through. In Firefox and IE10 you just get a blank screen.
You can view the code by viewing the source. Its all in-line and a very simple example to show the issue.
If you remove the following line:
ctx.globalCompositeOperation = "destination-atop";
Then you see the blue trees image with the ellipse on top of it as expected in all three browsers, so the code does "work".
Has anyone else experienced this and found a workaround?
I have searched and tried a couple of suggested solutions such as:
shape intersection with KineticJS
But all these still only seem to work in Chrome.
Any help or pointers would be appreciated.
Thanks
Tyrone.
We used to be able to cheat by grabbing the context of a layer, but now it’s unreliable (as you’ve discovered).
You can still get verrrrry hacky and do it like this: : http://jsfiddle.net/m1erickson/6fTQU/
But don’t ! (Even this hack doesn’t actually work on images with transparent pixels).
Instead, do it the official way by creating a Kinetic custom Shape Object.
Kinetic Shape gives you an official canvas and context to work with.
As a result, the globalCompositeOperation works fine (reliably!).
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/LtxEe/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<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.1.min.js"></script>
<style>
body{ background-color: ivory; }
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
var img=new Image();
img.onload=function(){
buildLayer(img);
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function buildLayer(img){
var myShape=new Kinetic.Shape({
drawFunc:function(canvas){
var ctx=canvas.getContext();
ctx.beginPath();
ctx.drawImage(img,0,0);
ctx.globalCompositeOperation="destination-atop";
ctx.arc(150,150,60,0,Math.PI*2,false);
ctx.closePath();
ctx.fill();
canvas.fillStroke(this);
},
x:0,
y:0,
width:img.width,
height:img.height
});
layer.add(myShape);
layer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>

Html5 Canvas to Canvas Blit

I need to set up a background canvas with a load of images drawn on at various places. Nothing changes on this background, so I want to do it all at once. I think I know how to do that. Then each frame I want to copy that background canvas (ultimately just a part of it) to my main screen canvas people see.
I am doing the following:
g_CanvasScreen = document.getElementById("m_Canvas");
g_CanvasScreenContext = g_CanvasScreen.getContext("2d");
g_OffScreenBackground = document.createElement("canvas");
g_OffScreenBackgroundContext = g_CanvasScreen.getContext("2d");
I believe this gets the main screen canvas from the hmtl5 page g_CanvasScreen.
I believe g_OffScreenBackground is a newly created canvas in memory.
Once all images have loaded I then draw all the images in the correct places to the background screen by calling the function:
DrawMapToBackground(g_OffScreenBackground, g_OffScreenBackgroundContext, 2000, 1600);
2000 x 1600 is the size of the offscreen background.
This then leads to the thing I am not sure about. I believe this will blit the background canvas to the main screen:
g_CanvasScreenContext.drawImage(g_OffScreenBackground,
0, 0, g_OffScreenBackground.width, g_OffScreenBackground.height,
screenX, screenY, g_OffScreenBackground.width, g_OffScreenBackground.height);
Is this last function correct? Can I do a canvas to canvas blit? Should I be doing this another way?
Instead of redrawing the background each time, just put 2 canvas’s on top of each other.
First draw the background image once on the bottom canvas.
Then use the top canvas to draw all your “changing” drawings.
Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/pSjEt/
<!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>
<style>
#container{
position:relative;
border:1px solid blue;
width:500px;
height:300px;
}
.subcanvs{
position:absolute;
width:100%;
height:100%;
}
</style>
<script>
$(function(){
var bk=document.getElementById("background");
var bkCtx=bk.getContext("2d");
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var bkimg=new Image();
bkimg.onload=function(){
bk.width=bkimg.width;
bk.height=bkimg.height;
canvas.width=bkimg.width;
canvas.height=bkimg.height;
bkCtx.drawImage(bkimg,0,0);
draw();
}
bkimg.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/skyGrass.png";
var x=50;
function draw(){
x+=5;
if(x>300){x=50;}
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.arc(x,100,30,0,Math.PI*2,false);
ctx.strokeStyle="gold";
ctx.fillStyle="yellow";
ctx.lineWidth=5;
ctx.stroke();
ctx.fill();
setTimeout(draw,1000);
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container">
<canvas id="background" class="subcanvs"></canvas>
<canvas id="canvas" class="subcanvs"></canvas>
</div>
</body>
</html>

HTML 5 canvas how can I extract and store an image from spritemap?

I'm also curious to know if this is a best practice.
I load a sprite map:
canvas = $('#GameCanvas')[0];
context = canvas.getContext('2d');
// load sprite map
spriteMap = new Image();
spriteMap.src = "resources/spritemap.png";
Now I've loaded my sprites, I want to draw them on the screen. I can do so by using context.drawImage(..) but:
I don't know if this is the best way, instead of just extracting each image I want and storing them separately eg. var playerCharacter = [cut the image out of the sprite map]
I want to colorise the images. If I pull out a 'white' sprite, I may then want to colorise it red, green, etc. I don't know how to do this yet, but it will probably require creating a new colorised Image so I'd have to pull it out of the spritemap anyway. I don't want to be recolorising constantly.
Any idea the best way of doing this?
Performance using sprites
Phrogz has some useful FPS tests for CSS vs Canvas here: Efficiency of <canvas> and <div>s They are live tests so you can run them in the environments you want to test.
Recoloring sprites
If you want to quickly take your white sprite and create red, green and blue sprites from it, you can use globalCompositeOperation=”source-in” to do that with very little work. Just use an image editor to create a cutout of the part of the image you want to recolor. Then use the code below to automatically create different colored sprites. I did the mask below in Photoshop using the magic want tool – 2 minutes tops!
Original Fish + Mask = Green Fish
Of course, you can create any color you want...even patterns instead of solid colors!
Here’s code. You will probably have to create your own image and mask because of CORS – stupid CORS !!
<!doctype html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
canvas{border:1px solid red;}
#wrapper{ position:relative;}
#overlay,#base{ position:absolute; top:0; left:0;}
</style>
<script>
$(function(){
var canvas=document.getElementById("overlay");
var ctx=canvas.getContext("2d");
var img=new Image();
img.onload=function(){
ctx.drawImage(img,0,0,img.width,img.height,0,0,overlay.width,overlay.height);
}
img.src="http://dl.dropbox.com/u/139992952/stackoverflow/fish%20overlay.png";
function draw(red,green,blue) {
ctx.save();
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle="rgb("+red+","+green+","+blue+")";
ctx.beginPath();
ctx.rect(0,0,overlay.width,overlay.height);
ctx.fill();
ctx.restore();
}
$("#red").click(function(){ draw(255,0,0); });
$("#green").click(function(){ draw(0,255,0); });
$("#blue").click(function(){ draw(0,0,255); });
});
</script>
</head>
<body>
<button id="red">Red Fish</button>
<button id="green">Green Fish</button>
<button id="blue">Blue Fish</button>
<div id="wrapper">
<img id="base" src="http://dl.dropbox.com/u/139992952/stackoverflow/fish.png" width=350 height=250>
<canvas id="overlay" width=350 height=250></canvas>
</div>
</body>
</html>

How to remove pixels from a HTML 5 video?

What I have so far: http://sem.serialshop.nl/video/
My goal is to manipulate the video pixels to show corresponding information inside the pupil when hovering one of the buttons. Can I delete the pixels inside the pupil, and replace it with an image?
Removing pixels from an mp4 video—removing pixels of an eye pupil
As darma says, you can probably finish your project by just using context.drawImage() to superimpose your image over the pupil. Here's how you do that.
Also, here's how you would remove the pixels of the pupil (as you asked).
Background
You can take an mp4 video and draw it frame-by-frame into a canvas.
The canvas drawing rate is quick enough that the results look as good as the video they were taken from.
More interestingly, you can manipulate each frame as it’s drawn into the canvas. This allows you to take the pixels of the pupil and replace them.
Manipulating pixels:
You manipulate the canvas frame by using context.getImageData() to grab the pixels into a data array.
Then you manipulate the data array in whatever way you wish.
Finally, you put the modified data array back into the canvas using context.putImageData().
The canvas then shows the modified pixels!
Your Solution
To solve your problem, we get the bounding-box containing the pupil. Every time we see a nearly-black pixel in that bounding box, we know it’s the pupil and we can modify that nearly-black pixel. In the following working code, we just change the pixel from nearly-black to pure red. However, you can do whatever you desire to the pupil pixels.
Here is code to draw the video with the pupil pixels colored red:
<!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>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var centerX=315;
var centerY=150;
var radius=10;
var rx=267;
var ry=98;
var rwidth=101;
var rheight=95;
var video = document.getElementById('vid');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var cw = 638;
var ch = 358;
canvas.width = cw;
canvas.height = ch;
video.addEventListener('play', function(){
draw(this,ctx,cw,ch);
},false);
function draw(video,context,w,h) {
if(video.paused || video.ended) return false;
context.drawImage(video,0,0,w,h);
// at this point you could also draw a second image
// into the pupil of the eye like this
// context.drawImage(myImage,rx,ry,rwidth,rheight);
// but what we do here is just put a red bounding box
// around the pupil so that we can see we are
// properly focusing on the pupil area
context.fillStyle="blue";
context.strokeStyle="red";
context.lineWidth=2;
context.beginPath();
context.rect(rx,ry,rwidth,rheight);
context.stroke();
extractPupil(context);
setTimeout(draw,150,video,context,w,h);
}
function extractPupil(context){
// get just the bounding rectangle of the pupil
// NOT the whole canvas.
var imgData=context.getImageData(rx,ry,rwidth,rheight);
var data=imgData.data;
for(var i=0;i<data.length;i+=4){
// if the pixel color is nearly black--change it to red
if(data[i]<20 && data[i+1]<20 && data[i+2]<20){
data[i]=255;
data[i+1]=0;
data[i+2]=0;
}
}
// put the modified pixels back into the canvas
// Now the pupil is colored pure red!
context.putImageData(imgData,rx,ry);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas"></canvas>
<video id="vid" controls loop>
<source src="eye.mp4" type=video/mp4>
</video>
</body>
</html>

HTML5, Canvas and FireFox

I have a couple questions about the HTML5-Canvas code shown below.
The text does not appear in Firefox 3.6 (it does appear in Chrome.)
Regarding the ctx variable (ctx = c.getContext("2d")), should this variable be reused over and over to create additional rectangles, shapes, etc. on the same canvas, or is it desirable to make new context variables for new rectangles, lines, etc.? (It seems to work both ways, but I'm not clear what is standard practice.)
<!DOCTYPE html>
<html lang="en">
<body>
<canvas id="myCanvas" width="400" height="350">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
var c = document.getElementById("myCanvas");
ctx = c.getContext("2d");
ctx.lineWidth = 5;
ctx.strokeStyle="black";
ctx.strokeRect(10,10,180,75);
ctx.textBaseline = 'Top';
ctx.font = '20px Sans-Serif';
ctx.fillStyle = 'blue';
ctx.fillText ("hello", 30, 50);
</script>
</body>
</html>
The problem seems to be with your call to textBaseline.
In playing with it in JSFiddle, it seems that this is case-sensitive...try making it lower-case: ctx.textBaseline = 'top'
Saved the fiddle link for you: http://jsfiddle.net/NG8Yf/