将画布内容复制到另一个类似于iphone的amaziograph app的画布

时间:2016-11-29 06:35:33

标签: android canvas

我正在开发类似于iPhone的Amaziograph的应用程序,也称为万花筒或曼陀罗。

直到现在我已经尝试并制作了该应用Circular canvas

的一个特定布局

我已经扩展了画布并制作了一个自定义画布,我将画布划分为9个部分,类似于图像,在绘制方法中,我旋转画布并将其内容复制到for循环中。这是我上面的圆形分割形状的画布类代码

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

2 个答案:

答案 0 :(得分: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);
                }
            }
        }
    }

您不必像我一样使用资源,但如果您在应用中硬编码大小,请确保乘以屏幕密度以获得正确的像素偏移。

答案 1 :(得分: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 + trace 3 =用户绘制的东西。 当你想要或者实时时,你可以将在这个视图上绘制的点发送到其他视图......或者当用户结束写入时发送字符串并提取点......

嗯,这只是一个想法,希望我帮助了;)