画布拖动中的奇怪行为

时间:2015-07-01 08:56:59

标签: android canvas bitmap drag gestures

我正在构建一个应用程序,它将在画布中包含图像拖动(位图)。我想实现它,所以它的工作和行动很好,任何人都可以帮助我吗? 这是代码:

    public boolean onTouchEvent(MotionEvent event) {
    mScaleDetector.onTouchEvent(event);

    final int action = event.getAction();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN & MotionEvent.ACTION_MASK: {
            final float xScale = event.getX();
            final float yScale = event.getY();

            mLastTouchX = xScale;
            mLastTouchY = yScale;
            mActivePointerId = event.getPointerId(0);
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            final int pointerIndex = event.findPointerIndex(mActivePointerId);
            final float xScale = event.getX(pointerIndex);
            final float yScale = event.getY(pointerIndex);
            if (!mScaleDetector.isInProgress()) {
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;
                mPosX += dx;
                mPosY += dy;

                invalidate();
            }
            mLastTouchX = x;
            mLastTouchY = y;
            if (event.getX() < overlay.getHeight()) {
                x = (int) event.getX();
            }
            if (event.getY() < overlay.getWidth()) {
                y = (int) event.getY();
            }
            invalidate();


            break;
        }
        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {
            final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = event.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = event.getX(newPointerIndex);
                mLastTouchY = event.getY(newPointerIndex);
                mActivePointerId = event.getPointerId(newPointerIndex);
            }
            break;
        }
    }

    return true;
}

void init(Context context) {
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    serverResult = Bitmap.createBitmap(mask.getWidth(),mask.getHeight(), Bitmap.Config.ARGB_8888);
    result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
    width = mask.getWidth();
    height = mask.getHeight();
    int overlayHeight = overlay.getHeight();
    int overlayWidth = overlay.getWidth();
    int imgHeight = originalImg.getHeight();
    int imgWidth = originalImg.getWidth();

    int heightFactor = imgHeight / overlayHeight;
    int widthFactor = imgWidth / overlayWidth;
    if (overlayHeight > imgHeight) {
        heightFactor = overlayHeight / imgHeight;
    }
    if (overlayWidth > imgWidth) {
        widthFactor = overlayWidth / imgWidth;
    }
    int newWidth;
    int newHeight;
    if (widthFactor != 0) {
        newWidth = imgWidth / widthFactor;
    } else {
        newWidth = imgWidth / heightFactor;
    }
    if (heightFactor != 0) {
        newHeight = imgHeight / widthFactor;
    } else {
        newHeight = imgHeight / heightFactor;
    }


    config = Bitmap.Config.ARGB_8888;
    DST_IN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    scaledImg = Bitmap.createScaledBitmap(originalImg, newWidth, newHeight, false);
    scaledImgFilterd = Bitmap.createScaledBitmap(originalImg, newWidth, newHeight, false);
    tempCanvas = new Canvas(result);
    imageCanvas = new Canvas(result);
    image = new GPUImage(context);




}

@Override
public void onDraw(Canvas canvas) {

    if (FILTER_APPLIED == 100) {
    if (filter != null) {
        image.setImage(scaledImg);
        image.setFilter(filter);
        scaledImgFilterd = image.getBitmapWithFilterApplied();
        FILTER_APPLIED = 0;
    }
    }

    paint.setXfermode(DST_IN);
    if(color == 0) {
        imageCanvas.drawColor(Color.WHITE);
    } else {
        imageCanvas.drawColor(color);

    }
    imageCanvas.scale(mScaleFactor, mScaleFactor);
    imageCanvas.drawBitmap(scaledImgFilterd, mLastTouchX, mLastTouchY, null);
    tempCanvas.drawBitmap(mask, 0, 0, paint);
    paint.setXfermode(null);
    canvas.drawBitmap(result, 0, 0, null);
    canvas.drawBitmap(overlay, 0, 0, null);

}

public void setColor(int color) {
    this.color = color;
    invalidate();
}

public void setFilter(GPUImageFilter filter) {
    this.filter = filter;
    FILTER_APPLIED = 100;
    invalidate();
}


private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));

        invalidate();
        return true;
    }
}

当我按照左上角拖动它时,一切都有点迟钝,有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

我不明白为什么它会缓慢(tbh,这是太多的代码),但下面是左上角拖动的解释

为了抵消左上角的拖动,您需要添加一些偏移变量,具体取决于您单击(触摸)图像的位置。

假设您触摸(touchX,touchY),您需要检查图像左上角的距离。

  1. 首先需要声明两个新变量,例如touchOffsetXtouchOffsetY
  2. 然后在触摸屏幕时定义新变量。

    touchOffsetX = touchX - image.x;

    touchOffsetY = touchY - image.y;

  3. 现在当您移动图像时,您可以根据以下设置其x和y坐标

    image.x = touchX - touchOffsetX;

    image.y = touchY - touchOffsetX;

  4. 您当然需要更改代码中的变量名称。

    下面是HTML5画布中的一个工作示例,可以进一步解释这个想法。

    var c = document.getElementById("canvas");
    var ctx = c.getContext("2d");
    c.width = 300;
    c.height = 200;
    
    var myRectangle = {
        x: 50,
        y: 130,
        w: 100,
        h: 50,
        drag: false
    }
    
    var mouseX = 0;
    var mouseY = 0;
    var mouseOffset = {x: 0, y:0}; // How far from the rectangle corner are we clicking?
    var background = "#0099CC"; 
    
    c.addEventListener("mousemove",mouseMove,false);
    c.addEventListener("mousedown",mouseDown,false);
    c.addEventListener("mouseup",mouseUp,false);
    
    //Getting the 
    function getMouseCoordinates() {
        event = event || window.event;
        mouseX = event.pageX - c.offsetLeft,
            mouseY = event.pageY - c.offsetTop;  
    }
    
    //This is what should be done while moving the mouse
    function mouseMove(event) {
        getMouseCoordinates();
        if (myRectangle.drag) {
            myRectangle.x = mouseX-mouseOffset.x;
            myRectangle.y = mouseY-mouseOffset.y;
        }
    }
    
    // This is what should happen when mouse button is pressed down
    function mouseDown() {
        if (mouseX > myRectangle.x &&
            mouseX < myRectangle.x+myRectangle.w &&
            mouseY > myRectangle.y &&
            mouseY < myRectangle.y + myRectangle.h) {
            if (document.getElementById("offset").checked) {
                mouseOffset.x = mouseX-myRectangle.x;
                mouseOffset.y = mouseY-myRectangle.y;
            }
            else {
                mouseOffset.x = 0;
                mouseOffset.y = 0;
            }
            
            myRectangle.drag = true;
            background = "#66FF99";
        }
    }
    
    // This is what should happen when mouse button is released back up
    function mouseUp() {
        myRectangle.drag = false;
        background = "#0099CC"; 
    }
    
    function draw() {
        // Clear the canvas before painting.
        ctx.fillStyle="#F0F0F0";
        ctx.fillRect(0,0,c.width,c.height);
        
        //Drawing the rectangle
        ctx.fillStyle=background;
        ctx.fillRect(myRectangle.x,myRectangle.y,myRectangle.w,myRectangle.h); 
        ctx.strokeRect(myRectangle.x,myRectangle.y,myRectangle.w,myRectangle.h);
        
        // Loop the drawing
        requestAnimationFrame(draw);
    }
    
    draw(); //we need to initiate the drawing to start it.
    <canvas id="canvas"></canvas><br />
    <input type="checkbox" id="offset">Check to use offset values.