html5 canvas 添加消除矩形 可移动重置缩放

HTML5-canvas 学习
~~canvas矩形框,可创建、消除、重置
最近需要完成一个小demo:初始化一个canvas,通过鼠标的down、move、up事件来画矩形框。
查了很多资料,发现都没有我想要的。只好自己尝试写一个,下面是一些参考的网址:
http://jsfiddle.net/a7mad24/aPLq5/
废话不多直接上demo:
首先是html页面:





<br> demo 1 <br>





















然后就是主要的js:shape.js
function Shape(x, y, w, h, fill, finished) {
this.x = x || 0;
this.y = y || 0;
this.w = w || 1;
this.h = h || 1;
this.fill = fill || 'rgba(96, 96, 96, .5)';
this.finished = finished;
}

Shape.prototype.draw = function(ctx) {
ctx.fillStyle = this.fill;
ctx.fillRect(this.x, this.y, this.w, this.h);
if(edit){
if (this.finished) {
var img=new Image();
img.src="x_20.png";
var ix=this.x + this.w - 20;
var iy=this.y;
if(this.w<0){
ix=this.x-20;
}
if(this.h<0){
iy=this.y+this.h;
}
ctx.drawImage(img, ix, iy, 20, 20);
}
}
}

Shape.prototype.contains = function(mx, my) {
return (this.x <= mx) && (this.x + this.w >= mx) && (this.y <= my) && (this.y + this.h >= my);
}

Shape.prototype.needClose = function(mx, my) {
var minx=this.x + this.w - 20;
var miny=this.y;
if(this.w<0){
minx=this.x-20;
}
if(this.h<0){
miny=this.y+this.h;
}
return (minx <= mx) && (minx+20 >= mx) && (miny <= my) && (miny + 20 >= my);
}

function CanvasState(canvas) {
this.canvas = canvas;
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;
if (document.defaultView && document.defaultView.getComputedStyle) {
this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
}
var html = document.body.parentNode;
this.htmlTop = html.offsetTop;
this.htmlLeft = html.offsetLeft;

this.valid = false;
this.shapes = [];
this.dragging = false;
this.isDown = false;
this.selection = null;
this.dragoffx = 0;
this.dragoffy = 0;
this.rect;

var myState = this;

var funSelectStart=function(e) {
e.preventDefault();
return false;
};

var funMouseDown=function(e) {
var mouse = myState.getMouse(e);
var mx = mouse.x;
var my = mouse.y;
if (!myState.isDown) {
var shapes = myState.shapes;
var l = shapes.length;
for (var i = l - 1; i >= 0; i--) {
if (shapes[i].needClose(mx, my)) {
var mySel = shapes[i];
myState.deleteShape(mySel);
myState.draw();
return;
}
if (shapes[i].contains(mx, my)) {
var mySel = shapes[i];
myState.dragoffx = mx - mySel.x;
myState.dragoffy = my - mySel.y;
myState.dragging = true;
myState.selection = mySel;
myState.valid = false;
return;
}
}
if (myState.selection) {
myState.selection = null;
myState.valid = false;
}

var newRect=new Shape(mx, my, 0, 0, 'rgba(96, 96, 96, .5)', false);
myState.addShape(newRect);
myState.setRect(newRect);
myState.setIsDown(true);
}

};

var funMouseMove= function(e) {
var mouse = myState.getMouse(e);
if (myState.dragging) {
myState.selection.x = mouse.x - myState.dragoffx;
myState.selection.y = mouse.y - myState.dragoffy;
myState.valid = false;
}
if (myState.isDown) {
var shapes = myState.shapes;
var rect=myState.rect;
var rex = rect.x;
var rey = rect.y;
var rew = mouse.x - rex
var reh = mouse.y - rey;
myState.deleteShape(rect);
var newRect=new Shape(rex, rey, rew, reh, 'rgba(96, 96, 96, .5)', false);
myState.addShape(newRect);
myState.setRect(newRect);
}
};

var funMouseUp=function(e) {
myState.dragging = false;
if (myState.isDown) {
var shapes = myState.shapes;
var rect=myState.rect;
var rex = rect.x;
var rey = rect.y;
var rew = rect.w;
var reh = rect.h;
myState.deleteShape(myState.rect);
var ifBadW=false;
var ifBadH=false;
if(rew>=0){
if(rew <= 2){
ifBadW=true;
}
if(rew<40){
rew=40;
}
}else{
if(rew >= -2){
ifBadW=true;
}
if(rew>-40){
rew=-40;
}
}
if(reh>=0){
if(reh <= 2){
ifBadH=true;
}
if(reh<20){
reh=20;
}
}else{
if(reh >= -2){
ifBadH=true;
}
if(reh>-20){
reh=-20;
}
}
if (!(ifBadW&&ifBadH)){
myState.addShape(new Shape(rex, rey, rew, reh, 'rgba(96, 96, 96, .5)', true));
}
}
myState.setIsDown(false);
};

this.start=function(){
canvas.addEventListener('selectstart',funSelectStart,false);
canvas.addEventListener('mousedown',funMouseDown, true);
canvas.addEventListener('mousemove',funMouseMove, true);
canvas.addEventListener('mouseup',funMouseUp,true);
};

this.end=function(){
canvas.removeEventListener('selectstart',funSelectStart,false);
canvas.removeEventListener('mousedown',funMouseDown, true);
canvas.removeEventListener('mousemove',funMouseMove, true);
canvas.removeEventListener('mouseup',funMouseUp,true);
};

setInterval(function() {
myState.draw();
},
myState.interval);
}

CanvasState.prototype.setIsDown = function(isDown) {
this.isDown = isDown;
}
CanvasState.prototype.setRect = function(rect) {
this.rect = rect;
}
CanvasState.prototype.addShape = function(shape) {
this.shapes.push(shape);
this.valid = false;
}

CanvasState.prototype.deleteShape = function(shape) {
this.shapes.splice($.inArray(shape, this.shapes), 1);
this.valid = false;
}

CanvasState.prototype.clear = function() {
this.ctx.clearRect(0, 0, this.width, this.height);
}

CanvasState.prototype.draw = function() {
if (!this.valid) {
var ctx = this.ctx;
var shapes = this.shapes;
this.clear();
var l = shapes.length;
for (var i = 0; i < l; i++) {
var shape = shapes[i];
if (shape.x > this.width || shape.y > this.height || shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
shapes[i].draw(ctx);
}
this.valid = true;
}
}

CanvasState.prototype.getMouse = function(e) {
var element = this.canvas,
offsetX = 0,
offsetY = 0,
mx, my;
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while (( element = element . offsetParent ));
}
offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;

return {
x: mx,
y: my
};
}
需要引入jquery-1.10.2.min.js
图片:
效果如下:
1. 初始化 不可修改。
2. 点击start 可通过叉来消除,鼠标按下、移动、松开来创建,同时矩形可通过鼠标来移动。
3. 点击end 去除叉,同时去除鼠标事件。
4. 点击reset 返回初始页面。
5. 点击create
可创建多个canvas,同时可以通过按钮来控制事件。


初级版本仅供参考,后续有升级版本,添加功能按比例缩放。 

你可能感兴趣的:(html5)