您的位置:首页 > Web前端 > JavaScript

Canvas---Canvas图像处理、图片查看器、图像拖动实现、js面向对象编程

2015-02-01 22:41 465 查看

模仿手机图像查看软件用canvas实现一个图像查看器。

目前实现:

1.利用将图像起点绘制到canvas之外的技术实现了图像的缩放。

包括,图像自适应、图像放大缩小

2.利用路径判断实现,鼠标拖动图像

目前存在问题:

1.由于拖动改变当前图像显示中点,而缩放的时候,使用的中点没有改变,造成跳动。

2.拖动没有做范围规范,可以拖动到死。

本次更新特色:

1.使用js面向对象编程重写大部分代码,代码重用性提高。

截图:

本文由 CSDN MIKUScallion 原创,更多canvas案例代码:http://blog.csdn.net/mikuscallion



源代码:

①本体代码

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
canvas{
background-color: black;
}
.contain{
margin: 0 auto;
width: 480px;
height: 640px;
position: relative;
}
.scaleSlider{
margin: 0px;
padding: 0px;
position: absolute;
/*旋转元素*/
transform:rotate(-90deg);
top: 70px;
left:400px;
}
</style>
<script type="text/javascript" src="MikuJsLibs/mikuCanvasContextHelp.js"></script>
<script type="text/javascript" src="MikuJsLibs/mikuCanvasClass.js"></script>
<script type="text/javascript" src="MikuJsLibs/mikuCanvasImageUtil.js"></script>
</head>
<body>
<div class="contain">
<input id="scaleSlider" class="scaleSlider" type="range" min="0.25" max="4" step="0.01" value="1" />
<canvas  id="canvas" width="480" height="640">
</canvas>
</div>
</body>
<script type = "text/javascript">
//变量------------------------------------------------------------------------------
//系统-------------------------------------------------
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
//控件--------------------------------------------------
var scaleSlider = document.getElementById("scaleSlider");
//做拖动效果相关变量--------------------
var objList = new MikuDrawedObjList();
var dragObj;
var offset = [];
var dragging = false;
//图片相关变量-----------------------------------
var mikuImage;
var image = new Image();
image.src ="miku01.jpg";
//自定义工具
var imageUtil = new MikuCanvasImageUtil();
//事件处理---------------------------------------------------------------------------
image.onload = function(){
init();
}
//缩放事件
scaleSlider.onchange = function(){
//清除屏幕
context.clearRect(0,0,canvas.width,canvas.height);
//根据缩放比例将图像在中心缩放
var scaleData = imageUtil.getImageScaleData(context,image,scaleSlider.value,false);
mikuImage.dRect.dx = scaleData.dx;
mikuImage.dRect.dy = scaleData.dy;
mikuImage.dRect.dw = scaleData.dw;
mikuImage.dRect.dh = scaleData.dh;
mikuImage.drawSelf(context);
}
//鼠标事件
canvas.onmousedown = function(e){
e.preventDefault();
var temp = windowToCanvas(e.clientX,e.clientY);
dragObj = objList.getClickObj(context,temp.x,temp.y);
if(dragObj == undefined){
return;
}
dragging = true;
offset.x = dragObj.dRect.dx - temp.x;
offset.y = dragObj.dRect.dy - temp.y;
}
canvas.onmousemove = function(e){
e.preventDefault();
var temp = windowToCanvas(e.clientX,e.clientY);
if(dragging){
//计算新顶点
var topPointX = temp.x + offset.x;
var topPointY = temp.y + offset.y;
//清除屏幕
context.clearRect(0,0,canvas.width,canvas.height);
//重新绘制
dragObj.dRect.dx = topPointX;
dragObj.dRect.dy = topPointY;
dragObj.drawSelf(context);
}
}
canvas.onmouseup = function(e){
e.preventDefault();
dragging = false;
offset = [];
dragObj = undefined;
}
//Init---------------------------------------------------------------------------
function init(){
mikuImage = new MikuImage(image);
objList.push(mikuImage);
var scaleData = imageUtil.getImageScaleData(context,image,1);
mikuImage.dRect.dx = scaleData.dx;
mikuImage.dRect.dy = scaleData.dy;
mikuImage.dRect.dw = scaleData.dw;
mikuImage.dRect.dh = scaleData.dh;
mikuImage.drawSelf(context);
}
</script>
</html>

②常用辅助类库

var drawingSurfaceImageData;
//将窗口坐标转换为Canvas坐标
function windowToCanvas(x,y){
var bbox = canvas.getBoundingClientRect();
return {
x : x - bbox.left*(canvas.width/bbox.width),
y : y - bbox.top*(canvas.height/bbox.height)
};
}
//保存当前绘图表面数据
function saveDrawingSurface(){
drawingSurfaceImageData = context.getImageData(0,0,canvas.width,canvas.height);
}
//还原当前绘图表面
function restoreDrawingSurface(){
context.putImageData(drawingSurfaceImageData,0,0);
}

③自定义类(class) 文件

//测试类
var MikuTest = function(){
//内部使用
var obj = 1;
//内部,外部通用
this.obj = undefined;
this.display = function(){
alert(obj);
}
}
//存储管理已经绘制的元素的一个类
//存储的元素必须实现
//1.创建自身路径:createPath(context);
//2.绘制自身:drawSelf(context);
var MikuDrawedObjList = function (){
var objList = [];

this.push = function (obj){
objList.push(obj);
}
this.getClickObj = function (context,x,y){
for(var i = 0; i<objList.length; i++){
//obj必须实现这个方法
objList[i].createPath(context);
if(context.isPointInPath(x,y)){
return objList[i];
}
}
}
this.drawAll = function (context){
objList.forEach(function(obj){
//obj必须实现这个方法
obj.drawSelf(context);
});
}
}
//Miku自定义图片类
var MikuImage = function(image){
this.image = image;
this.sRect = {sx:0,sy:0,sw:this.image.width,sh:this.image.height};
this.dRect = {dx:0,dy:0,dw:this.image.width,dh:this.image.height};

this.createPath = function(context){
context.beginPath();
context.rect(this.dRect.dx,this.dRect.dy,this.dRect.dw,this.dRect.dh);
context.closePath();
}
this.drawSelf = function(context){
context.drawImage(
this.image,
this.sRect.sx,this.sRect.sy,
this.sRect.sw,this.sRect.sh,
this.dRect.dx,this.dRect.dy,
this.dRect.dw,this.dRect.dh
);
}
}
//Miku自定义矩形类
var MikuRect = function(x,y,width,height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;

this.createPath = function(context){
context.beginPath();
context.rect(this.x,this.y,this.width,this.height);
context.closePath();
}
this.update = function(x,y,width,height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
this.drawSelf = function(context){
this.createPath(context);
context.stroke();
context.fill();
}
}


④图像处理相关自定义工具类

var MikuCanvasImageUtil = function(){
}
MikuCanvasImageUtil.prototype = {
//图像去适应放大scale倍后的canvas
//得到适应后图像的缩放数据
//noOver:是否阻止过度缩放 默认: true 阻止过度缩放
//date:2014-2-1
//author:MIKUScallion
getImageScaleData : function (context,image,scale,noOver){
//获得原有canvas长宽
var cw = context.canvas.width;
var ch = context.canvas.height;
//获得缩放后的canvas长宽
var scaledCw = cw*scale;
var scaledCh = ch*scale;
//获得相对新canvas的缩放对象
var scaleObj = this.getScaleObj(image,scaledCw,scaledCh,noOver);
//获取原有canvas中心坐标
var canvasCenterX = context.canvas.width/2;
var canvasCenterY = context.canvas.height/2;
//相对于canvas中心点计算,图像顶点
var imageStartPointX = canvasCenterX - scaleObj.width/2;
var imageStartPointY = canvasCenterY - scaleObj.height/2;
return {
dx:imageStartPointX,
dy:imageStartPointY,
dw:scaleObj.width,
dh:scaleObj.height
};
},
//让图像去缩放适应一个矩形
//得到适应后图像的宽高
//noOver:是否阻止过度缩放 默认: true 阻止过度缩放
//date:2014-2-1
//author:MIKUScallion
getScaleObj:function(image,width,height,noOver){
//默认不能过度缩放
noOver = noOver===undefined? true:noOver;
var scaleW,scaleH;
var widthLonger = image.width - width;
var heightLonger = image.height - height;
if(noOver){
//图像无需缩放
if(widthLonger <=0 && heightLonger<=0 ){
scaleW = image.width;
scaleH = image.height;
return {
width:scaleW,
height:scaleH
};
}
}
//固定宽度缩放
if(widthLonger >= heightLonger){
scaleW = width;
var percent = width/image.width;
scaleH = image.height*percent;
}
//固定长度缩放
else{
scaleH = height;
var percent = height/image.height;
scaleW = image.width*percent;
}
//----------------
return {
width:scaleW,
height:scaleH
};
}
}


本文由 CSDN MIKUScallion 原创,更多canvas案例代码:http://blog.csdn.net/mikuscallion
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: