将画布内容复制到另一个画布,类似于iPhone上的Amaziograph应用程序

9
我正在开发一款类似于iPhone上的Amaziograph应用程序,也被称为万花筒或曼陀罗。目前为止,我已经尝试并制作了一个特定的应用程序布局Circular canvas。我已经扩展了画布并制作了一个自定义画布,在绘制方法中,我将画布分成了9个部分,并在循环中旋转画布并复制其内容。这是我用于上述圆形分割形状的画布类代码。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.madala.mandaladrawing.R;
import com.madala.mandaladrawing.model.DrawingEvent;
import com.madala.mandaladrawing.utils.Common;


public class CanvasView extends View {
private final Context context;
private Bitmap bitmap;
private Canvas bitmapCanvas;
private Paint bitmapPaint;
private Path path = new Path();
private Paint brushPaint;

private int numberOfMirror = 5;
private int cx, cy;

public CanvasView(Context context) {
    super(context);
    this.context = context;
    init();
}

public CanvasView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    init();
}

public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.context = context;
    init();
}

private void init() {
    brushPaint = createPaint();
    brushPaint.setColor(0xffffffff);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
    canvas.drawPath(path, brushPaint);

    for (int i = 1; i < numberOfMirror; i++) {
        canvas.rotate(360f / numberOfMirror, cx, cy);
        canvas.drawPath(path, brushPaint);
    }
}

public void clearCanvas(){
    bitmapCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
    invalidate();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    setLayerType(View.LAYER_TYPE_HARDWARE, null);
    bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    bitmapCanvas = new Canvas(bitmap);
    bitmapPaint = new Paint(Paint.DITHER_FLAG);
    cx = w / 2;
    cy = h / 2;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(x, y);
            break;
        case MotionEvent.ACTION_UP:
            path.lineTo(x, y);
            drawToCanvas(path, brushPaint);
            path.reset();
            break;
        default:
            return false;
    }

    invalidate();
    return true;
}


private void drawToCanvas(Path path, Paint brushPaint) {
    bitmapCanvas.drawPath(path, brushPaint);
    for (int i = 1; i < numberOfMirror; i++) {
        bitmapCanvas.rotate(360f / numberOfMirror, cx, cy);
        bitmapCanvas.drawPath(path, brushPaint);
    }
}

public int getCurrentBrushColor() {
    return brushPaint.getColor();
}

public void setCurrentBrushColor(int color) {
    brushPaint.setColor(color);
}

private Paint createPaint() {
    Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
    p.setStrokeWidth(8f);
    p.setStyle(Paint.Style.STROKE);
    p.setStrokeJoin(Paint.Join.ROUND);
    p.setStrokeCap(Paint.Cap.ROUND);
    return p;
}
}

我无法实现下图所示的功能:Without Drawing 我想在一个框中绘制,然后它应该被复制到其他框中。如何实现这一点?一个小指南将非常有帮助。 With Drawing Drawing continues from one box to another

你能否检查一下我的解决方案并给予反馈?因为回答在截止日期之前没有被接受,所以我失去了两个声望点。谢谢。 - kris larson
2个回答

1
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- this has changed from first answer -->
    <dimen name="translation_size">30dp</dimen>
</resources>

...

    int size = getResources().getDimensionPixelSize(R.dimen.translation_size);

...

    private void drawToCanvas(Path path, Paint brushPaint) {
        bitmapCanvas.drawPath(path, brushPaint);  // just render normally
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(path, brushPaint);

        int xMax = getWidth() / size;
        int yMax = getHeight() / size;
        int xMin = -xMax;
        int yMin = -yMax;
        for (int x = xMin; x <= xMax; x++) {
            for (int y = yMin; y <= yMax; y++) {
                if ((Math.abs(x % 6) == 0 && Math.abs(y % 4) == 0) || 
                    (Math.abs(x % 6) == 3 && Math.abs(y % 4) == 2)) {
                    int xs = x * size;
                    int ys = y * size;
                    canvas.translate(xs, ys);
                    canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
                    canvas.translate(-xs, -ys);
                }
            }
        }
    }

你不必像我一样使用资源,但如果你在应用程序中硬编码了尺寸,请确保乘以屏幕密度以获得正确的像素偏移量。


我已经尝试了你的解决方案,但是对于六边形它并不起作用。它可以复制内容,但仅当我们在屏幕中间绘制时才有效,但在侧面绘制时无法正常工作。 - Sanjay Hirani
我想我会纠正答案,即使我现在无法获得奖励。 - kris larson

1
也许您可以将轨迹保存到数组中,并将其粘贴到其他绘图视图中。
@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //save initial x,y into array or send it to other canvas
            /*public general variable*/
            String Drawing +="[[x,y]";
            path.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            //save middle x,y into array or send it to other canvas
            String Drawing +=",[x,y]";
            path.lineTo(x, y);
            break;
        case MotionEvent.ACTION_UP:
            //save last point into array or send it to other canvas 
            String Drawing +=",[x,y]]";
            path.lineTo(x, y);
            drawToCanvas(path, brushPaint);
            path.reset();
            break;
        default:
            return false;
    }

    invalidate();
    return true;
}

字符串结果应该是所有用户痕迹。
[[x,y],[x,y],[x,y],[x,y],[x,y]],  trace 1
[[x,y],[x,y],[x,y],[x,y],[x,y]],  trace 2
[[x,y],[x,y],[x,y],[x,y],[x,y]],  trace 3
etc..

trace1 + trace2 + trace3 = 用户绘制的东西。 当您想要或者可能实时发送在这个视图上绘制的点到其他视图……或者当用户结束写作时,发送字符串并提取点……

嗯,这只是一个想法,希望我能帮到您;)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接