How to draw a path with variable stroke width

后端 未结 1 1163
耶瑟儿~
耶瑟儿~ 2020-12-29 15:32

My code is basically from this example (http://corner.squareup.com/2010/07/smooth-signatures.html) and Google APIs (FingerPaint) but now I want to use the class Veloci

1条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-29 16:09

    You can use split your path object every time your stroke value changes depending on velocity. In you SignatureView class add

    private Path mPath = new Path();
    ArrayList mPaths = new ArrayList();
    

    and take another ArrayList to keep stroke value for each path

    ArrayList strokes = new ArrayList();
    

    add a variable lastStroke along with lastTouchX and lastTouchY. I will recommend you to make lastStroke of type int.

    private int lastStroke = -1; //give an initial value
    

    now your onTouchEvent method should be something like this

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();
        int historySize = event.getHistorySize();
        int eventStroke= //calculate stroke size with velocity and make it between 1-10 or any range you seem fit
    
        switch (event.getAction()) {
    
            case MotionEvent.ACTION_DOWN:
    
                resetDirtyRect(eventX, eventY);
                mPath.reset();
                mPath.moveTo(eventX, eventY);
                mX = eventX;
                mY = eventY;
                break;
    
            case MotionEvent.ACTION_MOVE:
    
                float dx = Math.abs(eventX - mX);
                float dy = Math.abs(eventY - mY);
    
                if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                    if(lastStroke != evetnStroke){
                        mPath = new Path();
                        mPath.moveTo(mX,mY);
                        mPaths.Add(mPath);
                        mStrokes.Add(eventStroke);
                    }
                    mPath.quadTo(mX, mY, (eventX + mX)/2, (eventY + mY)/2);
                    mX = eventX;
                    mY = eventY;
                }
    
                for (int i = 0; i < historySize; i++) {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                }
                break;
    
            case MotionEvent.ACTION_UP:
    
                for (int i = 0; i < historySize; i++) {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                }
    
               mPath.lineTo(mX, mY);
               break;
    
            default:
                Log.d(TAG, "Ignored touch event: " + event.toString());
            return false;
        }
        // Include half the stroke width to avoid clipping.
        invalidate(     (int) (dirtyRect.left - HALF_STROKE_WIDTH),
                        (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                        (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                        (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));
    
        lastTouchX = eventX;
        lastTouchY = eventY;
        lastStroke = eventStroke;
        return true;
    }
    

    and your ondraw method would be

    @Override
    protected void onDraw(Canvas canvas) {
        for(int i=0; i

    this is the basic idea. you need to modify it to make it work.

    0 讨论(0)
提交回复
热议问题