
我这里认为大家都稍微了解甚至熟悉canvas的一些API,就不具体说,每一个参数代表什么意思了。
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>加载平移放大缩小示例</title>
<style>
html,body{
margin:0px;
padding:0px;
}
canvas{
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="800"></canvas>
<script type="text/javascript" src="mainjs"></script>
</body>
</html>
var canvas,context;
function int(){
canvas=documentgetElementById('canvas');
context=canvasgetContext('2d');
}
加载
创建一个对象之后,不能马上绘制到canvas上面,因为还没有加载完成。所以我们需要监听对象加载完事件,然后再去绘制。
var img,//对象
imgIsLoaded//是否加载完成;
function loadImg(){
img=new Image();
imgonload=function(){
imgIsLoaded=true;
//draw image
}
imgsrc="mapjpg";
}
绘制
绘制图像一个函数就可以搞定,但是需要记录这个图像的左上角坐标以及缩放比例。
var imgX,imgY,imgScale;
function drawImage(){
contextclearRect(0,0,canvaswidth,canvasheight);
contextdrawImage(img,0,0,imgwidth,imgheight,imgX,imgY,imgwidthimgScale,imgheightimgScale);
}
平移
html5事件最小细度在DOM上,所以我们无法对canvas上的图像做监听,只能对canvas监听。
首先监听鼠标mousedown事件,等事件发生之后,再监听鼠标mousemove事件和mouseup事件
mousemove事件发生之后,获得鼠标移动的位移,相应的的位置改变多少
mouseup事件发生之后,取消对mousemove以及mouseup事件监听
canvasonmousedown=function(event){
var pos=windowToCanvas(canvas,eventclientX,eventclientY);
canvasonmousemove=function(event){
canvasstylecursor="move";
var pos1=windowToCanvas(canvas,eventclientX,eventclientY);
var x=pos1x-posx;
var y=pos1y-posy;
pos=pos1;
imgX+=x;
imgY+=y;
drawImage();
}
canvasonmouseup=function(){
canvasonmousemove=null;
canvasonmouseup=null;
canvasstylecursor="default";
}
}
function windowToCanvas(canvas,x,y){
var bbox = canvasgetBoundingClientRect();
return {
x:x - bboxleft - (bboxwidth - canvaswidth) / 2,
y:y - bboxtop - (bboxheight - canvasheight) / 2
};
}
缩放
其实缩放很简单,稍微复杂的是,如何让鼠标成为放大或者缩小的中心。如果数学几何不好,计算公式就可能看不明白了。
canvasonmousewheel=canvasonwheel=function(event){//chrome firefox浏览器兼容
var pos=windowToCanvas(canvas,eventclientX,eventclientY);
eventwheelDelta=eventwheelDeltaeventwheelDelta:(eventdeltaY(-40));
if(eventwheelDelta>0){
imgScale=2;
imgX=imgX2-posx;
imgY=imgY2-posy;
}else{
imgScale/=2;
imgX=imgX05+posx05;
imgY=imgY05+posy05;
}
drawImage();
}
这个时候,基本功能就实现了,加载一张和加载多张都差不多,维护每一张的位置和大小,下面来整理一下代码吧。
var canvas,context;
var img,//对象
imgIsLoaded,//是否加载完成;
imgX=0,
imgY=0,
imgScale=1;
(function int(){
canvas=documentgetElementById('canvas');
context=canvasgetContext('2d');
loadImg();
})();
function loadImg(){
img=new Image();
imgonload=function(){
imgIsLoaded=true;
drawImage();
}
imgsrc="mapjpg";
}
function drawImage(){
contextclearRect(0,0,canvaswidth,canvasheight);
contextdrawImage(img,0,0,imgwidth,imgheight,imgX,imgY,imgwidthimgScale,imgheightimgScale);
}
canvasonmousedown=function(event){
var pos=windowToCanvas(canvas,eventclientX,eventclientY);
canvasonmousemove=function(event){
canvasstylecursor="move";
var pos1=windowToCanvas(canvas,eventclientX,eventclientY);
var x=pos1x-posx;
var y=pos1y-posy;
pos=pos1;
imgX+=x;
imgY+=y;
drawImage();
}
canvasonmouseup=function(){
canvasonmousemove=null;
canvasonmouseup=null;
canvasstylecursor="default";
}
}
canvasonmousewheel=canvasonwheel=function(event){
var pos=windowToCanvas(canvas,eventclientX,eventclientY);
eventwheelDelta=eventwheelDeltaeventwheelDelta:(eventdeltaY(-40));
if(eventwheelDelta>0){
imgScale=2;
imgX=imgX2-posx;
imgY=imgY2-posy;
}else{
imgScale/=2;
imgX=imgX05+posx05;
imgY=imgY05+posy05;
}
drawImage();
}
function windowToCanvas(canvas,x,y){
var bbox = canvasgetBoundingClientRect();
return {
x:x - bboxleft - (bboxwidth - canvaswidth) / 2,
y:y - bboxtop - (bboxheight - canvasheight) / 2
};
看到你标题说HTML5能画地图,就来了兴趣,特意百度了下资料,不过资料上的地图好像是一张,并非画出来的,不免有些失望。
以下是我搜到的一篇资料,你说的缩放、拖动上面都写了。
>
如果是要将一个Bitmap绘制到界面上,那就直接用Canvas#drawBitmap()方法绘制即可
如果是要从一个已有的canvas获取bitmap对象,可尝试下面的办法:
1、用BitmapcreateBitmap()方法,创建一个与目标canvas大小相同的空白Bitmap对象
2、用Canvas#setBitmap()方法,将创建的bitmap设置为Canvas对象的Bitmap。之后所有对目标canvas的绘制 *** 作都会绘制在这个bitmap上,相当于将canvas中的内容转换为了一个单独的bitmap
另外,如果创建canvas对象的时候调用的是canvas(Bitmap bitmap)方法的话,那么创建canvas的时候就应该已经有现存的bitmap对象了,这种情况应该不需要转换
我们可以使用Matrix 来放缩我们得到的Bitmap 从而使我们的BItmap适应我们的手机屏幕
首先我们得先获取我们的手机屏幕的大小
WindowManager wm = (WindowManager) getContext()getSystemService(ContextWINDOW_SERVICE);
int width = wmgetDefaultDisplay()getWidth();
int height = wmgetDefaultDisplay()getHeight();
然后我们构造一个新的Matrix对象,自己完成写一个函数,如下:
public Bitmap resizeBitmap(Bitmap bitmap,int w,int h){
if(bitmap!=null)
{
int width = bitmapgetWidth();
int height = bitmapgetHeight();
int newWidth = w;
int newHeight = h;
float scaleWight = ((float)newWidth)/width;
float scaleHeight = ((float)newHeight)/height;
Matrix matrix = new Matrix();
matrixpostScale(scaleWight, scaleHeight);
Bitmap res = BitmapcreateBitmap(bitmap, 0,0,width, height, matrix, true);
return res;
}
else{
return null;
}
}
这样我们通过这个函数返回的Bitmap对象就是可以适应我们手机屏幕大小的了。。
近期在做数字展厅的时候,原来是横屏的默认,考虑到竖屏应用场景,这里做了一个判断屏幕方向然后自动使用横屏背景和竖屏背景的逻辑。
原来横屏的时候是OK的,但一到竖屏就crash,报如下错误
经查,竖屏背景尺寸为288018XX,明显偏大
调整为198011XX后,程序正常
上面的API就是设置你要画图时保存图的BITMAP,你画的东西就在BITMAP中。这个bitmap可以通过BitmapcreateBitmap(width, height, config)来新建,而不是你从资源里加载的。
先setDrawingCacheEnabled(true);
你要显示的都显示出来后buildDrawingCache();
最后Bitmap b=getDrawingCache();
就ok了,这样就截屏了
这一报错在微信开发者论坛中被多次提及,最多被提到的就是这一方法。
wxdraw()是一个异步执行的api,canvasToTempFilePath需要在其回调中执行。延迟 200毫秒 一般就可以解决这个问题。
当这个api只执行一次时延迟200毫秒其实无所谓,但是多次调用时,这个延迟也浪费了不少时间。对于性能强大的手机,这也是一种浪费,一般只有性能较弱的安卓机才会出现这个问题。所以我更建议大家使用下面一个。
canvasToTempFilePath本身也是异步api,有错误回调可以使用。
我的项目中需要绘制的大小为180180px,耗时基本在50-100ms左右。报错一次以后canvas基本也就准备好了,一般不会错第三遍。
题外话:这一个api的耗时与画布大小密切相关,也建议大家绘制时一定要控制好canvas画布大小。比方说,绘制200200的,canvas要大小一致。尤其是数量比较大时,在模拟器上体现不出差别,但是手机上影响很大。
mesh是网格,蒙皮相当于从原图里取出(meshWidth+1)(meshHeight+1)个点放到verts中参数里面没有体现初始位置,初始位置就是固定的,是把verts的点刚好铺在原图上对应的位置新的像素位置就是verts,改变verts就能扭曲比喻成皮肤,捏皮肤就能改变皮肤下面的东西查看原帖>>
以上就是关于如何在html5的canvas绘制地图全部的内容,包括:如何在html5的canvas绘制地图、HTML5 Canvas元素绘制地图,已绘制出地图,并且地图可放大缩小,怎样实现鼠标移动到一幢楼时显示楼的名称、如何将Canvas 上的内容转换为一张Bitmap-Android开发问答等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)