简体   繁体   English

Android Java,在缩放的画布上绘制

[英]Android Java, draw on a scaled canvas

i'm developing an android drawing application, it has a relativelayout with a custom view in it for drawing with. 我正在开发一个Android绘图应用程序,它有一个relativelayout,其中有一个自定义视图用于绘图。 So far it all works except when I scale the canvas the drawing happens in the wrong spot, it's probably best to show the code rather than try to explain it. 到目前为止,一切都有效,除非我缩放画布时绘图发生在错误的位置,最好显示代码而不是尝试解释它。 Yes I have tried with using path.offset but with no success. 是的我尝试过使用path.offset但没有成功。 The main issue is that when you draw on it when it's been scaled in, while it paints in the right spot, the path is too sensitive, when your finger is centered it's fine but if you go up/down or side to side the path moves faster than your finger. 主要问题是,当你在缩放时绘制它时,当它在正确的位置绘制时,路径太敏感,当你的手指居中时它很好但是如果你上下/左右或上下路径比你的手指移动得更快。

package com.nick.sketchr;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;

public class CustomCanvas extends View {
private Bitmap  mBitmap;
private Canvas  mCanvas;
private Path    mPath;
private Paint   mBitmapPaint;
private Paint   mPaint;
private float   old_scale;
private float   dmx,dmy;
private double  scale;
private long    timevar2;
private Rect    bounds;
public CustomCanvas(Context c) {
    super(c);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0xFF000000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(3);
    dmx = Main_App.w/2/2;
    dmy = Main_App.h/2/2;
    scale = 1;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(Main_App.w/2, Main_App.h/2, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
    mBitmap.eraseColor(Color.WHITE);
}

@Override
protected void onDraw(Canvas canvas) {
    float sc = (float) scale;
    canvas.scale(sc, sc, Main_App.w/2, Main_App.h/2);
    canvas.drawBitmap(mBitmap, dmx, dmy, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}
private void touch_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }
}
private void touch_up() {
    mPath.lineTo(mX, mY);
    mPath.offset(-dmx, -dmy); //this is the problem area
    //also the path shows wrong when canvas is scaled... o_o
    mCanvas.drawPath(mPath, mPaint);
    mPath.reset();
}
@Override
public boolean onTouchEvent(MotionEvent event){
    float x = event.getX()/(float)scale+bounds.left;
    float y = event.getY()/(float)scale+bounds.top;
    if(event.getPointerCount() == 2){
        timevar2 = event.getEventTime();
        float newx = event.getX(0);
        float newy = event.getY(0);
        float oldx = event.getX(1);
        float oldy = event.getY(1);
        mPath.reset();
        float equa = (float) (Math.pow(newx - oldx, 2) + Math.pow(newy - oldy, 2));
        float cscale = (float) Math.sqrt(equa)/100;
        float scaled = (cscale - old_scale);
        if(scaled < -0.1){
            if(scale > 0.1){
              scale -= 0.03;
            }
        }
        if(scaled > 0.1){
            scale += 0.03;
        }
        dmx = (float) (((newx + oldx)/2)-(Main_App.w/2/2)*scale);
        dmy = (float) (((newy + oldy)/2)-(Main_App.h/2/2)*scale);
        old_scale = cscale;
        invalidate();
        return true;
    }
    long dt = event.getEventTime() - timevar2;
    if(dt < 100){
        return true;
    }
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touch_up();
            invalidate();
            break;
        }
    return true;
}

public void clear(){
    mBitmap.eraseColor(Color.TRANSPARENT);
    invalidate();
    System.gc();
}
}

Not entirely sure but you may be scaling the Canvas incorrectly. 不完全确定,但您可能无法正确缩放画布。 Instead try: 而是尝试:

canvas.scale(width_of_canvas, height_of_canvas)

in your onDraw() method.Currently you are using a scale value of 1 . 在你的onDraw()你使用的是1的比例值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM