Android共享绘图画布路径绘制顺序

时间:2020-03-25 14:06:34

标签: android firebase canvas firebase-realtime-database path

我正在开发一个协作艺术应用程序,其中用户可以使用FireBase实时数据库在画布上一起绘制一段距离。我已经理解到一个用户屏幕上绘制的细分出现在另一用户的屏幕上,反之亦然。

但是,一旦将片段从Firebase中拉出,它将在背景中绘制该片段,而不是在用户的“绘画”上绘制该片段。

有没有办法告诉程序始终将不同的段相互画在上面?

The orange line drawn on the right phone appears in the background of the left phone

我把我使用的代码片段放在这里:

这是我从FireBase中提取分段的地方:

        mListener=mRef.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                String name=dataSnapshot.getKey();
                if (!mOutstandingSegments.contains(name)) {
                    Segment segment = dataSnapshot.getValue(Segment.class);

                    drawSegmentPath(segment.getPoints(), segment.getColor(), segment.getBlurEnabled(), segment.getStrokeWidth());

                    //invalidate();
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {            
                }
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    } 

该段通过以下方法转换为路径:

    public void drawSegmentPath(List<Point> segmentPoints, int color, boolean blurEnabled, float strokeWidth){
        Point currentSegmentPoint = segmentPoints.get(0);

        Path newSegmentPath = new Path();
        FingerPath fireBasePath = new FingerPath(color, blurEnabled, strokeWidth, newSegmentPath);

        firePath.add(fireBasePath);

        newSegmentPath.reset();

        newSegmentPath.moveTo(currentSegmentPoint.x, currentSegmentPoint.y);

        Point nextSegmentPoint = null;
        invalidate();

        for (int i = 1; i < segmentPoints.size(); i++) {
            nextSegmentPoint = segmentPoints.get(i);
            newSegmentPath.quadTo(currentSegmentPoint.x, currentSegmentPoint.y, (int)((nextSegmentPoint.x + currentSegmentPoint.x) / 2), (int)((nextSegmentPoint.y + currentSegmentPoint.y) / 2));
            currentSegmentPoint = nextSegmentPoint;
            System.out.println("Current Segment Points: " + currentSegmentPoint);

            invalidate();
        }


        if (nextSegmentPoint != null) {
            newSegmentPath.lineTo(nextSegmentPoint.x, nextSegmentPoint.y);
            invalidate();
        }

    }

然后在onDraw()中,将路径绘制在与用户在其自己的手机上绘制的线条相同的画布(mCanvas)上:


    @Override
        protected void onDraw(Canvas canvas){
            canvas.save();
            mCanvas.drawColor(Color.WHITE);

            for(FingerPath fireBasePath : firePath){
                mPaint.setColor(fireBasePath.myColor);
                mPaint.setStrokeWidth(fireBasePath.strokeWidth);
                mPaint.setMaskFilter(null);

                if (fireBasePath.blurEnabled){testPaint.setMaskFilter(mBlur);}

                mCanvas.drawPath(fireBasePath.path, mPaint);
            }

            for(FingerPath fp : paths){
                mPaint.setColor(fp.myColor);
                mPaint.setStrokeWidth(fp.strokeWidth);
                mPaint.setMaskFilter(null);

                if (fp.blurEnabled){mPaint.setMaskFilter(mBlur);}

                mCanvas.drawPath(fp.path, mPaint);

            }

            canvas.drawBitmap(mBitmap, drawMatrix, mBitmapPaint);
            canvas.concat(drawMatrix);
            canvas.restore();
            invalidate();

    }

当用户通过不断在Segment类中添加点来将手指移到屏幕上方时,就形成了一个细分:

    pivate void touchStart(float positionX, float positionY){

        mPath = new Path();
        FingerPath fp = new FingerPath(currentBrushColor, blurEnabled, strokeWidth, mPath);
        mCurrentSegment = new Segment(currentBrushColor, strokeWidth, blurEnabled);
        paths.add(fp);

        mPath.reset();
        mPath.moveTo(positionX, positionY);

        mX = positionX;
        mY = positionY;

        mCurrentSegment.addPoint((int)mX, (int)mY);

    }

    private void touchMove(float positionX, float positionY){
        float dx = Math.abs(positionX - mX);
        float dy = Math.abs(positionY - mY);

        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE){
            mPath.quadTo(mX, mY, (positionX + mX)/2, (positionY + mY)/2);
            mX = positionX;
            mY = positionY;
            mCurrentSegment.addPoint((int)mX, (int)mY);
        }
    }

然后,当用户完成绘制时,将线段推入FireBase:

    private void touchUp(){
        mPath.lineTo(mX,mY);

        DatabaseReference segmentRef=mRef.push();
        final String segmentName=segmentRef.getKey();
        currentSegmentKey=segmentName;
        mOutstandingSegments.add(segmentName);

        Segment mySegment = new Segment(mCurrentSegment.getColor(), mCurrentSegment.getStrokeWidth(), blurEnabled);
        for (Point point: mCurrentSegment.getPoints()) {
            mySegment.addPoint(point.x , point.y );
        }

        System.out.println("Segment is: " + mySegment);

        // Save our segment into Firebase.
        segmentRef.setValue(mySegment, new DatabaseReference.CompletionListener() {
            @Override
            public void onComplete(DatabaseError error, DatabaseReference firebaseRef) {
                if (error != null) {
                    throw error.toException();
                }
                mOutstandingSegments.remove(segmentName);
            }
        });
    }

下面的onTouchEvent lstener中调用了不同的onTouch方法:

    @Override
    public boolean onTouchEvent(MotionEvent event){

            float positionX = event.getX()
            float positionY = event.getY()

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    touchStart(positionX, positionY);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touchMove(positionX, positionY);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touchUp();
                    invalidate();

                    break;
            }
        }

        return true;
    }

0 个答案:

没有答案