canvas-demo
ä¸ãè稿æè·¯ï¼HTML + JSï¼
1. å建ç»å¸èæ¯
使ç¨divæ ç¾ï¼è®¾ç½®èæ¯æ ·å¼ï¼height: 100vh;å
满å±å¹ï¼
APIï¼application programming interfaceï¼åºç¨ç¨åºç¼ç¨æ¥å£
2. è·åçåid
// æä¸é¼ æ
- é¼ æ ç¹å»äºä»¶ï¼onmousedownï¼ç»å®èæ¯divï¼ç¹å»è§¦åäºä»¶ï¼
å建ä¸ä¸ªé»ç¹ï¼åé divï¼ç¨style设置divæ ·å¼ï¼å ¶ä¸å¼å¯ç»å¯¹å®ä½ï¼ä½¿ç¨clientXãclientYè·åé¼ æ ç¹å»ä½ç½®ï¼æ·»å å°çåçtopãleftä¸ï¼
//移å¨é¼ æ
é¼ æ 移å¨äºä»¶ï¼onmousemoveï¼ç»å®èæ¯divï¼ç§»å¨è§¦åäºä»¶ï¼
ï¼åç¹å»äºä»¶ï¼
//å½¢æ类似ç»æ¿å½ä»¤
å ¨å±å£°æä¸ä¸ªâå¼å ³æé®âï¼ï¼painting=falseï¼
å½ç¹å»äºä»¶ï¼onmousedownï¼åçï¼âå¼å ³æé®âå为true
å¨ç§»å¨äºä»¶ï¼onmousemoveï¼ä¸æ·»å å¤æï¼å½âå¼å ³æé®â为trueæ¶ï¼å¼å§ç§»å¨äºä»¶
//æ¾å¼é¼ æ
é¼ æ æ¾å¼äºä»¶ï¼onmouseupï¼ç»å®èæ¯divï¼æ¾å¼è§¦åäºä»¶ï¼
å å ¥âå¼å ³æé®âï¼æ¾å¼é¼ æ ï¼âå¼å ³æé®âå为falseï¼åæ¢ä½ç»ã
ç¨åºä»£ç
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ç»æ¿</title>
<style>
body{
margin: 0
}
#canvas{
background: green;
height: 100vh;
position: relative;
}
</style>
<script src="./main.js" type="text/javascript"></script>
</head>
<body>
<div id="canvas"></div>
</body>
</html>
JS
window.onload = function(){
var div = document.getElementById('canvas');
var painting = false;
//æä¸é¼ æ
div.onmousedown = function(a){
painting = true;
var x = a.clientX;
var y = a.clientY;
var divA = document.createElement('div');
divA.style = "width: 6px; height: 6px;" + "background: black; border-radius: 3px;" +
"position: absolute; left: " + (x-3) + "px;" + "top: " + (y-3) + "px;"
div.appendChild(divA);
};
div.onmousemove = function(a){
if (painting){
var x = a.clientX;
var y = a.clientY;
var divA = document.createElement('div');
divA.style = "width: 6px; height: 6px;" + "background: black; border-radius: 3px;" +
"position: absolute; left: " + (x-3) + "px;" + "top: " + (y-3) + "px;"
div.appendChild(divA);
}else{
}
};
div.onmouseup = function(){
painting = false;
}
}
äºã使ç¨canvasæ ç¾å¶ä½ç»æ¿ï¼åæ¶è§£å³è¿ç»æ§é®é¢
1. è·å API 2D ä¸ä¸æç¯å¢
var context = xxx.getcontext('2d');
2. å®ç°ç»æ¿æä½
//æä¸é¼ æ
å¨ç¹å»äºä»¶ï¼onmousedownï¼ä¸ï¼è·åå°ç¹å»é¼ æ çä½ç½®ä¿¡æ¯ï¼æ·»å ç»åå½æ°
//移å¨é¼ æ
åçï¼å¨ç§»å¨äºä»¶ä¸æ·»å ç»åå½æ°ï¼è·åé¼ æ 移å¨å°çä½ç½®ï¼
为å®ç°å线çè¿è´¯æ§ï¼è®¾ç½®ç»çº¿å½æ°ï¼è¿æ¥åå两åï¼å®ç°è¿è´¯ï¼ï¼
为æ¤ï¼å¨å ¨å±ä½ç¨å声æä¸ä¸ªåå¸ï¼var lastPoint = {x: undefined, y: undefined}
ï¼
ç¹å»äºä»¶åçï¼onmousedownä¸ç lastPoint åå§åä¸ºé¼ æ ç¹å»ä½ç½®ï¼
å¨ç§»å¨äºä»¶ä¸ï¼å£°æä¸ä¸ªnewPointï¼æ¥æ¶é¼ æ 移å¨å°çä½ç½®ï¼
æ¥ä¸æ¥æ顺åºæ§è¡ç»åå½æ°ãç»çº¿å½æ°ï¼å ¶ä¸ç»çº¿å½æ°ç第ä¸ä¸ªåæ 为lastPointï¼ç¬¬äºä¸ªåæ 为newPointï¼
ï¼éç¹+解é¢ç¹ï¼
å½é¼ æ æç»æä¸ç§»å¨ï¼ä¸ºè§£å³ä¹åçæ¯ä¸ªç¹é½ä¸ç¬¬ä¸ç¹è¿çº¿çé®é¢ï¼éä¸åæ´æ°lastPoint
lastPoint = newPoint;
3. å°ç»åãå线åè½å°è£
//å½æ°å®ç°ä½¿ç¨canvasçAPI
function drawCircle(x, y, radius){
context.beginPath();
context.fillStyle = 'black';
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
}
function drawLine(x1, y1, x2, y2) {
context.beginPath();
context.strokeStyle = 'black';
context.moveTo(x1, y1); //èµ·ç¹
context.lineWidth = 5;
context.lineTo(x2, y2); //ç»ç¹
context.stroke();
context.closePath();
}
4. ç¨åºä»£ç
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
<script src="./main.js"></script>
</head>
<body>
<canvas id="xxx" width=300 height=300></canvas>
</body>
</html>
CSS
#xxx{
background: green;
display: block;
}
body{
margin: 0;
}
JS
window.onload = function(){
var yyy = document.getElementById('xxx');
var context = yyy.getContext('2d');
var painting = false;
var lastPoint = {x: undefined, y: undefined};
yyy.onmousedown = function(event){
painting = true;
var x = event.clientX;
var y = event.clientY;
lastPoint = {'x': x,'y': y};
drawCircle(x, y, 1);
}
yyy.onmousemove = function(event){
if(painting){
painting = true;
var x = event.clientX;
var y = event.clientY;
var newPoint = {'x': x,'y': y};
drawCircle(x, y, 1);
drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y);
//ä¸åæ´æ°å½åç¹ï¼é²æ¢åºç°æ¯ä¸ªç¹é½åªå第ä¸ç¹è¿æ¥
lastPoint = newPoint;
}
}
yyy.onmouseup = function(event){
painting = false;
}
function drawCircle(x, y, radius){
context.beginPath();
context.fillStyle = 'black';
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
}
function drawLine(x1, y1, x2, y2) {
context.beginPath();
context.strokeStyle = 'black';
context.moveTo(x1, y1); //èµ·ç¹
context.lineWidth = 5;
context.lineTo(x2, y2); //ç»ç¹
context.stroke();
context.closePath();
}
}
ä¸ã ä¼å
1. è·å页é¢å®½é«
//è·å页é¢å®½é«ä¸è½ç¨CSSï¼ä¼åºç°é¼ æ 移ä½bug
var pageWidth = document.documentElement.clientWidth;
var pageHeight = document.documentElement.clientHeight;
yyy.width = pageWidth;ï¼é¡µé¢å®½é«æ·»å å°canvasçåç宽é«ä¸ï¼
yyy.height = pageHeight;
//ç±äºç¨æ·ç§»å¨é¡µé¢åï¼ç»å¸å®½é«ååçååï¼æ以çå¬é¡µé¢çªå£å¤§å°
//çå¬é¡µé¢çªå£ï¼è·åå®æ¶å®½é«
window.onresize = function(){
var pageWidth = document.documentElement.clientWidth;
var pageHeight = document.documentElement.clientHeight;
yyy.width = pageWidth;
yyy.height = pageHeight;
}
//å¯å°éå¤ç¨å°çè¯å¥å°è£
2. å¯å»æç»åå½æ°
å»æåï¼ä¾ç¶å¯ä»¥ç»å¾ï¼ä½ç¹å»ä¸ä¼æç»å¾ï¼ç§»å¨ä¼æ§è¡ç»çº¿å½æ°ã
3. æ·»å æ©¡ç®æ¦åè½
//å¢å æ©¡ç®æ¦æé®ï¼è®¾ç½®æµ®å¨å®ä½å°ç»å¸ä¸ï¼
//ç¨JSå°æ©¡ç®æ¦ä¹è®¾ä¸ºå¸å°è½¬æ¢å½æ°ï¼
var eraserEnabled = false;
eraser.onclick = function(){
eraserEnabled = !eraserEnabled;
}
//ç¹å»äºä»¶ä¸ï¼ç¹å»è¿å
¥å¤æï¼è¥æ©¡ç®æ¦å¼å¯å为æ§è¡æ¸
é¤è¯å¥ï¼å¦åæ§è¡åäºä»¶ï¼
//æ¤å¤ï¼ç±äºusingåå¨if-elseè¯å¥åä¸ï¼åªæ两å¥é½æ·»å using=trueï¼using=trueæè½ç»§æ¿å°ç§»å¨äºä»¶ï¼onmousemoveï¼ä¸ï¼
if(eraserEnabled){
using = true;//ç¹å»é¼ æ ææ¦ï¼ä¸ºä½¿ç§»å¨äºä»¶çusing=trueï¼æ¤å¥å¿
é¡»åå¨
context.clearRect(x-5, y-5, 10, 10);
}else{
using = true;
lastPoint = {'x': x,'y': y};
//drawCircle(x, y, 1);
}
//移å¨äºä»¶ä¸ï¼åæ ·ç¹å»è¿å
¥å¤æï¼è¥æ©¡ç®æ¦å¼å¯å为æ§è¡æ¸
é¤è¯å¥ï¼å¦åæ§è¡åäºä»¶ï¼
//ä½å¨è¿å
¥å¼å¯æ©¡ç®æ¦çå¤æä¸åï¼è¦åè¿è¡å¤æï¼çæ¯å¦é¼ æ 被ç¹å»ï¼ç¹å»åè¿è¡ç§»å¨æ¸
é¤ï¼
ï¼æ¤å¥æ¯ä¸ºäºé²æ¢å¼å¯æ©¡ç®æ¦æé®åï¼ç§»å¨é¼ æ ç´æ¥è¿è¡äºæ¸
é¤ï¼
if(eraserEnabled){
//å¼å¯æ©¡ç®æ¦ï¼å¤ææ¯å¦æå¨ç¨æ©¡ç®æ¦
if(using){
context.clearRect(x-5, y-5, 10, 10);
}
}else{
if(using){
//using = true;
//console.log(using)
var newPoint = {'x': x,'y': y};
//drawCircle(x, y, 1);
drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y);
//ä¸åæ´æ°å½åç¹ï¼é²æ¢åºç°æ¯ä¸ªç¹é½åªå第ä¸ç¹è¿æ¥
lastPoint = newPoint;
}
}
4. å°è£ å½æ°
window.onload = function(){
var yyy = document.getElementById('xxx');
var context = yyy.getContext('2d');
autoSetCanvasSize(yyy);
listenToMouse(yyy);
/************************************/
æé®é¨å
var eraserEnabled = false;
eraser.onclick = function(){
eraserEnabled = !eraserEnabled;
}
/********************************/
function autoSetCanvasSize(canvas){
setCanvasSize();
//çå¬é¡µé¢çªå£ï¼è·åå®æ¶å®½é«
window.onresize = function(){
setCanvasSize();
}
function setCanvasSize(){
//è·å页é¢å®½é«
var pageWidth = document.documentElement.clientWidth;
var pageHeight = document.documentElement.clientHeight;
canvas.width = pageWidth;
canvas.height = pageHeight;
}
}
function listenToMouse(canvas){
var using = false;
var lastPoint = {x: undefined, y: undefined};
canvas.onmousedown = function(event){
var x = event.clientX;
var y = event.clientY;
if(eraserEnabled){
using = true;//ç¹å»é¼ æ ææ¦ï¼ä¸ºä½¿ç§»å¨äºä»¶çusing=trueï¼æ¤å¥å¿
é¡»åå¨
context.clearRect(x-5, y-5, 10, 10);
}else{
using = true;
lastPoint = {'x': x,'y': y};
//drawCircle(x, y, 1);
}
}
canvas.onmousemove = function(event){
var x = event.clientX;
var y = event.clientY;
if(eraserEnabled){
//å¼å¯æ©¡ç®æ¦ï¼å¤ææ¯å¦æå¨ç¨æ©¡ç®æ¦
if(using){
context.clearRect(x-5, y-5, 10, 10);
}
}else{
if(using){
//using = true;
//console.log(using)
var newPoint = {'x': x,'y': y};
//drawCircle(x, y, 1);
drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y);
//ä¸åæ´æ°å½åç¹ï¼é²æ¢åºç°æ¯ä¸ªç¹é½åªå第ä¸ç¹è¿æ¥
lastPoint = newPoint;
}
}
}
canvas.onmouseup = function(event){
using = false;
}
}
function drawCircle(x, y, radius){
context.beginPath();
context.fillStyle = 'black';
context.arc(x, y, radius, 0, Math.PI * 2);
context.fill();
}
function drawLine(x1, y1, x2, y2) {
context.beginPath();
context.strokeStyle = 'black';
context.moveTo(x1, y1); //èµ·ç¹
context.lineWidth = 5;
context.lineTo(x2, y2); //ç»ç¹
context.stroke();
context.closePath();
}
}
5. ä¼åå½æ°
//æ·»å æ©¡ç®ç»ç¬è½¬æ¢
æè·¯ï¼å¨ä¸ä¸ªçåé设置两个æé®ï¼éè¿æ¹åclassåå®ç°æé®è½¬æ¢ã
为橡ç®åç»ç¬æé®ç»å®æé®ç¹å»äºä»¶ï¼onclickï¼ï¼ç±JSæ¥æ¹åçåçç±»åï¼åå§æ x ç±»åï¼âcssä¸è®¾ç½®æé®åå§ç¶æ为ï¼åªæ¾ç¤ºæ©¡ç®æé®ï¼æ·»å äºç±»å x åçç¶æ为ï¼åªæ¾ç¤ºç»ç¬æé®ã
<div id="actions" class="actions">
<button id="eraser">æ©¡ç®æ¦</button>
<button id="brush">ç»ç¬</button>
</div>
.actions > #brush{
display: none;
}
.actions.x > #brush{
display: inline-block;
}
.actions.x > #eraser{
display: none;
}
//åæ¶ææ©¡ç®æ¦å¼å ³ä¹æ¾å ¥å个ç¹å»æé®äºä»¶ï¼ä»¥ä¸ç¨åºæ¿æ¢æé®é¨åï¼
var eraserEnabled = false;
eraser.onclick = function(){
eraserEnabled = true;
actions.className = 'actions x';
}
brush.onclick = function(){
eraserEnabled = false;
actions.className = 'actions';
}
上一篇: yii 操作session
下一篇: 简单的MD5加密demo
推荐阅读