ใน HTML5 นั้นจะมี Element ที่ชื่อว่า canvas ที่เราสามารถใช้ jQuery หรือ JavaScript ควบคุมการทำงานของมันได้ ไม่ว่าจะวาดภาพ วาดวงกลม ใส่รูป เราก็สามารถใส่เข้าไปใน canvas ได้
ถ้าเพื่อนๆที่เคยใช้พวก Java applet คงจะพอนึกภาพออกนะครับว่า Canvas นั้นมันก็เป็นพื้นที่สี่เหลี่ยมที่เอาไว้ใช้แสดงผลกราฟฟิก ที่เราสามารถจะควบคุมได้ สามารถควบคุมในระดับ pixel ได้เลยทีเดียว
Canvas นั้นก็เหมือนๆกับ Element อื่นๆครับ สามารถกำหนด Style ให้ได้ไม่ว่าจะเป็นสี ขนาดความกว้าง ความสูง กำหนดทำแหน่งได้ด้วย
ผมก็เลยเอาตัวอย่างเว็บที่ผมเขียนขึ้นมาให้ดูว่ามันเป็นอย่างไร
ผมไม่ได้เขียนขึ้นเองมาทั้งหมด นำมาจากหลายที่ แก้ไขและเพิ่มเติม
ก็เลยจะนำมาแบ่งให้เพื่อนๆศึกษากันดู ^^
------------------------------------------------------------------------------------------------------------
canvas.html
<html>
<head>
<script type="text/javascript" src="canvas2image.js"> </script>
</head>
<body>
<center>
<button id="pencil" onclick="Default()"> Default </button>
<input type="color" name="favcolor" id="favcolor" onchange="selectColor()"/>
<button id="sizeP" onclick="sizeP()"> + </button>
<button id="sizeD" onclick="sizeD()"> - </button>
<input type="file" NAME="Files" onchange="preview(this)" />
<button id="Submit" onclick="Submit()"> Submit </button>
</br>
<button id="clears" onclick="Pencil()"> Pencil </button>
<button id="Circle" onclick="Circle()"> Circle </button>
<button id="Rectangle" onclick="Rectangle()"> Rectangle </button>
<button id="Ellipse" onclick="Ellipse()"> Ellipse </button>
<button id="export" onclick="exportImage()"> Export </button>
<button id="eraser" onclick="eraser()"> Eraser </button>
<button id="clears" onclick="Clear_image()"> Clear </button></br>
<canvas id="canvas" width="800" height="500" style="border: 1px solid black;"></canvas>
<div id="coord"></div></center>
<script>
var mouse = {x: 0, y: 0};
var start_mouse = {x: 0, y: 0};
var radius = 5;
var canvas = document.getElementById('canvas'),
coord = document.getElementById('coord'),
context = canvas.getContext('2d'), // get 2D context
rect = {},
drag = false;
imgCat = new Image();
/*********** draw image *************/
imgCat.src = 'Untitled.jpg';
imgCat.onload = function() { // wait for image load
context.drawImage(imgCat, 0, 0); // draw imgCat on (0, 0)
context.lineWidth = radius;
context.strokeStyle = '#000000';
context.lineWidth = 5;
};
function getPath(){
var str = document.getElementById('blaat').value;
// lastIndexOf('\\') you need to use two \\'s because you use \ to escape
str = str.substring(0, str.lastIndexOf('\\'));
//if you want a closing \ just add a \ to the str (str += '\')
document.getElementById('verborgenBlaat').value = str;
// alert to proof it sets the directory
alert(document.getElementById('verborgenBlaat').value)
}
function preview(test){
var source=test.value;
alert(source);
}
function fileSelected(){
alert( document.forms[0].files.value);
}
function Submit(){
alert(document.forms[0].getElementById('files').value);
}
/*********** handle mouse events on canvas **************/
function Pencil(){
context.strokeStyle = document.getElementById("favcolor").value;
var mousedown = false;
canvas.onmousedown = function(e) {
var pos = fixPosition(e, canvas);
mousedown = true;
context.beginPath();
context.moveTo(pos.x, pos.y);
return false;
};
canvas.onmousemove = function(e) {
var pos = fixPosition(e, canvas);
coord.innerHTML = '(' + pos.x + ',' + pos.y + ')';
if (mousedown) {
context.lineTo(pos.x, pos.y);
context.stroke();
}
};
canvas.onmouseup = function(e) {
mousedown = false;
};
}
/********** utils ******************/
// Thanks to http://stackoverflow.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element/4430498#4430498
function fixPosition(e, gCanvasElement) {
var x;
var y;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;
return {x: x, y:y};
}
function exportImage() {
window.open(canvas.toDataURL(),'_blank','width=800,height=600');
//window.open("http://www.w3schools.com")
}
function Default(){
context.strokeStyle = document.getElementById("favcolor").value;
context.lineWidth = 5;
}
function Clear_image() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
function sizeP() {
radius++;
context.lineWidth = radius;
}
function sizeD() {
if(radius==1){}
else{
radius--;
context.lineWidth = radius;
}
}
function eraser(){
Pencil();
context.strokeStyle = "#FFFFFF";
}
function showR(){
document.write(radius);
}
//////////////////////////////////////////////////////
function Rectangle(){
context.strokeStyle = document.getElementById("favcolor").value;
var mousedown = false;
canvas.onmousedown = function(e) {
var pos = fixPosition(e, canvas);
mousedown = true;
context.drawImage(canvas, 0, 0);
context.beginPath();
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
return false;
};
canvas.onmousemove = function(e) {
var pos = fixPosition(e, canvas);
coord.innerHTML = '(' + pos.x + ',' + pos.y + ')';
/* if (mousedown) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY ;
context.clearRect(0,0,canvas.width,canvas.height);
context.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
}
*/
};
canvas.onmouseup = function(e) {
if (mousedown) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY ;
context.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
}
mousedown = false;
};
}
function Circle(){
context.strokeStyle = document.getElementById("favcolor").value;
var mousedown = false;
canvas.onmousedown = function(e) {
var pos = fixPosition(e, canvas);
mousedown = true;
context.drawImage(canvas, 0, 0);
context.beginPath();
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
return false;
};
canvas.onmousemove = function(e) {
var pos = fixPosition(e, canvas);
coord.innerHTML = '(' + pos.x + ',' + pos.y + ')';
/* if (mousedown) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY ;
context.clearRect(0,0,canvas.width,canvas.height);
context.strokeRect(rect.startX, rect.startY, rect.w, rect.h);
}
*/
};
canvas.onmouseup = function(e) {
if (mousedown) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY ;
var radius = Math.max(
Math.abs(rect.w),
Math.abs(rect.h)
) / 2;
context.arc(rect.startX, rect.startY, radius, 0, Math.PI*2, false);
context.stroke();
context.closePath();
}
mousedown = false;
};
}
</script>
</body>
</html>
------------------------------------------------------------------------------------------------------------
canvas2image.js
var Canvas2Image = (function() {
// check if we have canvas support
var bHasCanvas = false;
var oCanvas = document.createElement("canvas");
if (oCanvas.getContext("2d")) {
bHasCanvas = true;
}
// no canvas, bail out.
if (!bHasCanvas) {
return {
saveAsBMP : function(){},
saveAsPNG : function(){},
saveAsJPEG : function(){}
}
}
var bHasImageData = !!(oCanvas.getContext("2d").getImageData);
var bHasDataURL = !!(oCanvas.toDataURL);
var bHasBase64 = !!(window.btoa);
var strDownloadMime = "image/octet-stream";
// ok, we're good
var readCanvasData = function(oCanvas) {
var iWidth = parseInt(oCanvas.width);
var iHeight = parseInt(oCanvas.height);
return oCanvas.getContext("2d").getImageData(0,0,iWidth,iHeight);
}
// base64 encodes either a string or an array of charcodes
var encodeData = function(data) {
var strData = "";
if (typeof data == "string") {
strData = data;
} else {
var aData = data;
for (var i=0;i<aData.length;i++) {
strData += String.fromCharCode(aData[i]);
}
}
return btoa(strData);
}
// creates a base64 encoded string containing BMP data
// takes an imagedata object as argument
var createBMP = function(oData) {
var aHeader = [];
var iWidth = oData.width;
var iHeight = oData.height;
aHeader.push(0x42); // magic 1
aHeader.push(0x4D);
var iFileSize = iWidth*iHeight*3 + 54; // total header size = 54 bytes
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256); iFileSize = Math.floor(iFileSize / 256);
aHeader.push(iFileSize % 256);
aHeader.push(0); // reserved
aHeader.push(0);
aHeader.push(0); // reserved
aHeader.push(0);
aHeader.push(54); // dataoffset
aHeader.push(0);
aHeader.push(0);
aHeader.push(0);
var aInfoHeader = [];
aInfoHeader.push(40); // info header size
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0);
var iImageWidth = iWidth;
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256); iImageWidth = Math.floor(iImageWidth / 256);
aInfoHeader.push(iImageWidth % 256);
var iImageHeight = iHeight;
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256); iImageHeight = Math.floor(iImageHeight / 256);
aInfoHeader.push(iImageHeight % 256);
aInfoHeader.push(1); // num of planes
aInfoHeader.push(0);
aInfoHeader.push(24); // num of bits per pixel
aInfoHeader.push(0);
aInfoHeader.push(0); // compression = none
aInfoHeader.push(0);
aInfoHeader.push(0);
aInfoHeader.push(0);
var iDataSize = iWidth*iHeight*3;
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256); iDataSize = Math.floor(iDataSize / 256);
aInfoHeader.push(iDataSize % 256);
for (var i=0;i<16;i++) {
aInfoHeader.push(0); // these bytes not used
}
var iPadding = (4 - ((iWidth * 3) % 4)) % 4;
var aImgData = oData.data;
var strPixelData = "";
var y = iHeight;
do {
var iOffsetY = iWidth*(y-1)*4;
var strPixelRow = "";
for (var x=0;x<iWidth;x++) {
var iOffsetX = 4*x;
strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+2]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX+1]);
strPixelRow += String.fromCharCode(aImgData[iOffsetY+iOffsetX]);
}
for (var c=0;c<iPadding;c++) {
strPixelRow += String.fromCharCode(0);
}
strPixelData += strPixelRow;
} while (--y);
var strEncoded = encodeData(aHeader.concat(aInfoHeader)) + encodeData(strPixelData);
return strEncoded;
}
// sends the generated file to the client
var saveFile = function(strData) {
document.location.href = strData;
}
var makeDataURI = function(strData, strMime) {
return "data:" + strMime + ";base64," + strData;
}
// generates a <img> object containing the imagedata
var makeImageObject = function(strSource) {
var oImgElement = document.createElement("img");
oImgElement.src = strSource;
return oImgElement;
}
var scaleCanvas = function(oCanvas, iWidth, iHeight) {
if (iWidth && iHeight) {
var oSaveCanvas = document.createElement("canvas");
oSaveCanvas.width = iWidth;
oSaveCanvas.height = iHeight;
oSaveCanvas.style.width = iWidth+"px";
oSaveCanvas.style.height = iHeight+"px";
var oSaveCtx = oSaveCanvas.getContext("2d");
oSaveCtx.drawImage(oCanvas, 0, 0, oCanvas.width, oCanvas.height, 0, 0, iWidth, iHeight);
return oSaveCanvas;
}
return oCanvas;
}
return {
saveAsPNG : function(oCanvas, bReturnImg, iWidth, iHeight) {
if (!bHasDataURL) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var strData = oScaledCanvas.toDataURL("image/png");
if (bReturnImg) {
return makeImageObject(strData);
} else {
saveFile(strData.replace("image/png", strDownloadMime));
}
return true;
},
saveAsJPEG : function(oCanvas, bReturnImg, iWidth, iHeight) {
if (!bHasDataURL) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var strMime = "image/jpeg";
var strData = oScaledCanvas.toDataURL(strMime);
// check if browser actually supports jpeg by looking for the mime type in the data uri.
// if not, return false
if (strData.indexOf(strMime) != 5) {
return false;
}
if (bReturnImg) {
return makeImageObject(strData);
} else {
saveFile(strData.replace(strMime, strDownloadMime));
}
return true;
},
saveAsBMP : function(oCanvas, bReturnImg, iWidth, iHeight) {
if (!(bHasImageData && bHasBase64)) {
return false;
}
var oScaledCanvas = scaleCanvas(oCanvas, iWidth, iHeight);
var oData = readCanvasData(oScaledCanvas);
var strImgData = createBMP(oData);
if (bReturnImg) {
return makeImageObject(makeDataURI(strImgData, "image/bmp"));
} else {
saveFile(makeDataURI(strImgData, strDownloadMime));
}
return true;
}
};
})();
------------------------------------------------------------------------------------------------------------