如何在固定的canvas画布内缩放

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在固定的canvas画布内缩放相关的知识,希望对你有一定的参考价值。

参考技术A

如何在固定的canvas画布内缩放

<script type=\'text/javascript\' src=jquery.js></script>
<script type=\'text/javascript\'>
function bindchangesize(jq)
var touchstarttime = 0; 记录手指按住萤幕的时间
var dbx = 0;
var dby = 0;
var pretevent = false;
var startX; 按住时座标X
var startY; 按住时座标Y
var startLen;
var isstart = false;
var isonefinger = true; 判断是否是一只手指按住萤幕
jq.bind(\'touchstart\',_touchstart);
jq.bind(\'touchmove\',_touchmove);
jq.bind(\'touchend\',_touchend);
function _touchstart(e)
isstart = true;
isonefinger = true;
if(pretevent)
e.sPropagation();

var ttime = (new Date()).getTime();
var touch;
if(typeof e.clientX != \'undefined\')
touch = e;
else
touch = e.originalEvent.touches[0];
if(e.originalEvent.touches && e.originalEvent.touches.length > 1)
isonefinger = false;


startX = touch.clientX;
startY = touch.clientY;
if(!isonefinger)
var touch1 = e.originalEvent.touches[1];
var x = touch1.clientX;
var y = touch1.clientY;
startLen = Math.sqrt(Math.pow(startX - x,2) + Math.pow(startY - y,2));

if(!isonefinger)
touchstarttime = ttime;


function _touchmove(e)
var touch;
var jq0 = $(this);
jq0.s(true,true);
if(typeof e.clientX !=\'undefined\')
touch=e;
else
touch= e.originalEvent.touches[0];

var x = touch.clientX;
var y = touch.clientY;
var zoom = jq0.get(0).style.zoom;
if(zoom == 0) zoom = 1;
if(!isonefinger)
var touch1 = e.originalEvent.touches[1];
var x1 = touch1.clientX;
var y1 = touch1.clientY;
var nowlen = Math.sqrt(Math.pow(x1 - x,2) + Math.pow(y1 - y,2));
var len = nowlen - startLen;
if(len < 0)
len = nowlen;
else
len = startLen + len;

var percent = len/startLen;
var changezoom = zoom*percent;
if(changezoom>5)
changezoom = 5;

if(changezoom<0.5)
changezoom = 0.5;

jq0.animate(zoom:changezoom);


function _touchend(e)
startX = null;
startY = null;
isstart = false;
isonefinger=true;
startLen = 0;


function bindevent()
var jqcanvas1 = $(\'#canvasid\'); 通过ID找到canvas
bindchangesize(jqcanvas1);

</script>
简单的写了一个,你试试
通过zoom属性来控制的

简单思路就是:
禁止浏览器缩放;
处理touch事件,当为两指操作缩放时停止事件传播;
canvas方面,始终设定context的原点在canvas元素中心点;
每次触发缩放就clear掉整个画布,然后使用context.scale缩放,然后全部重新画。

画布可绘制对象和居中缩放

【中文标题】画布可绘制对象和居中缩放【英文标题】:Canvas drawables and centered zooming 【发布时间】:2012-02-01 17:59:00 【问题描述】:

我正在使用Google tutorial 为我的画布实现缩放功能。我在画布上绘制了几个项目,我可以通过Canvas.translate(dx,dy) 将其与项目一起移动。为了让我确定这些项目是否在画布平移后被触摸,我将用于Canvas.translate(dx,dy) 的画布偏移量减去触摸位置。一旦我在图片中引入缩放,它就会变得有点棘手。如果我使用Canvas.scale(sx,sy) 并执行(touchX-offsetX)/scaleFactor,则缩放后触摸位置的平移完美。但是,如果包含枢轴位置Canvas.scale(sx,sy,px,py),则上面的代码不起作用。作为触摸翻译的一部分,我如何着手考虑枢轴位置?我通过执行以下操作来设置我的枢轴位置,

    public boolean onScaleBegin(ScaleGestureDetector detector) 
    mScaleX = detector.getFocusX();
    mScaleY = detector.getFocusY();
    return true;

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

简单的解决方案

 public class ScalableImageView extends View 
    Matrix drawMatrix = new Matrix();
    ScaleGestureDetector detector;
    public ScalableImageView(Context context, AttributeSet attrs)  
         @Override
        public boolean onScale(ScaleGestureDetector detector) 

            drawMatrix.postScale(detector.getScaleFactor(), detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
            invalidate();
            return true;
        

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) 
            return drawMatrix != null;
        

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) 

        
    

    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);

        canvas.save();
        canvas.concat(drawMatrix);
        // ... draw here
        // for example drawable.draw()
        canvas.restore();
    


【讨论】:

以上是关于如何在固定的canvas画布内缩放的主要内容,如果未能解决你的问题,请参考以下文章

JS中canvas画布绘制中如何实现缩放,位移,旋转

在 KineticJS 中缩放到固定点

canvas 画布与画布内容都缩小如何实现?

调整 HTML5 画布元素的大小

如何在画布内拖动用户控件

缩放图像以适合画布