如何绘制路径与帆布可变宽度 [英] How to draw path with variable width in canvas

查看:162
本文介绍了如何绘制路径与帆布可变宽度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的code以下行画上一个画布路径,到目前为止,一切工作正常,我可以用这个code轻易画出路径。

I am using the following line of code to draw path on a Canvas, So far everything works fine and i can easily draw path using this code.

但是,现在我们的要求是绘制路径与可变宽度,是指道路使用者平局是根据用户应用的pressure,我的意思是说,如果用户采用光pressure路径将是薄,并且如果用户施加的高pressure路径将是厚等。到目前为止,我成功地绘制可变宽度也路径,但绘制的线条不流畅。为什么它发生得如此,什么我想念我的code

But now our requirement is to draw path with variable width, means the path user draw is based on the pressure applied by the user, I mean to say if the user applied light pressure the path will be thin and if the user applied high pressure the path will be thick and so on. So far i succeeded in drawing path with variable width also, but the line drawn are not smooth. Why its happening so, is anything i miss in my code

帮我短了这一点。

code,我用来绘制路径有一个宽度

 public class FingerPaint extends GraphicsActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }

    public void colorChanged(int color) 
    {

    }

    public class MyView extends View 
    {
        private static final float STROKE_WIDTH = 5f;       

        private Paint paint = new Paint();

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

        ArrayList<Integer> mStrokes = new ArrayList<Integer>();

        private float lastTouchX;
        private float lastTouchY;
        private final RectF dirtyRect = new RectF();

        private int lastStroke = -1;
        int variableWidthDelta = 0;

        private float           mX, mY;

        private static final float       TOUCH_TOLERANCE = 4;

        public MyView(Context context) 
        {
            super(context);

            paint.setAntiAlias(true);
            paint.setDither(true);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeCap(Paint.Cap.ROUND);    
            paint.setStrokeWidth(STROKE_WIDTH);
        }

        public void clear()
        {
            mPath.reset();
            // Repaints the entire view.
            invalidate();
        }

        @Override
        protected void onDraw(Canvas canvas) 
        {
            for(int i=0; i<mPaths.size();i++)
            {
                paint.setStrokeWidth(mStrokes.get(i));
                canvas.drawPath(mPaths.get(i), paint);
            }
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) 
        {
            float eventX = event.getX();
            float eventY = event.getY();
            int historySize = event.getHistorySize();

            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:
                {                   
                    if (event.getPressure()>=0.00 && event.getPressure()<0.05)
                    {
                        variableWidthDelta = -2;
                    }
                    else if (event.getPressure()>=0.05 && event.getPressure()<0.10)
                    {
                        variableWidthDelta = -2;
                    }
                    else if (event.getPressure()>=0.10 && event.getPressure()<0.15)
                    {
                        variableWidthDelta = -2;
                    }
                    else if (event.getPressure()>=0.15 && event.getPressure()<0.20)
                    {
                        variableWidthDelta = -2;
                    }
                    else if (event.getPressure()>=0.20 && event.getPressure()<0.25)
                    {
                        variableWidthDelta = -2;
                    }
                    else if (event.getPressure() >= 0.25 && event.getPressure()<0.30)
                    {
                        variableWidthDelta = 1;
                    }
                    else if (event.getPressure() >= 0.30 && event.getPressure()<0.35)
                    {
                        variableWidthDelta = 2;
                    }
                    else if (event.getPressure() >= 0.35 && event.getPressure()<0.40)
                    {
                        variableWidthDelta = 3;
                    }
                    else if (event.getPressure() >= 0.40 && event.getPressure()<0.45)
                    {
                        variableWidthDelta = 4;
                    }
                    else if (event.getPressure() >= 0.45 && event.getPressure()<0.60)
                    {
                        variableWidthDelta = 5;
                    }

                    float dx = Math.abs(eventX - mX);
                    float dy = Math.abs(eventY - mY);

                    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
                    {
                        if(lastStroke != variableWidthDelta)
                        {   
                            mPath.lineTo(mX, mY);

                            mPath = new Path();
                            mPath.moveTo(mX,mY);
                            mPaths.add(mPath);
                            mStrokes.add(variableWidthDelta);
                        }

                        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;
                }
            }

            // Include half the stroke width to avoid clipping.
            invalidate();

            lastTouchX = eventX;
            lastTouchY = eventY;
            lastStroke = variableWidthDelta;

            return true;
        }

        private void expandDirtyRect(float historicalX, float historicalY) 
        {
            if (historicalX < dirtyRect.left)
            {
                dirtyRect.left = historicalX;
            } 
            else if (historicalX > dirtyRect.right)
            {
                dirtyRect.right = historicalX;
            }
            if (historicalY < dirtyRect.top) 
            {
                dirtyRect.top = historicalY;
            } 
            else if (historicalY > dirtyRect.bottom) 
            {
                dirtyRect.bottom = historicalY;
            }
        }

        /**
         * Resets the dirty region when the motion event occurs.
         */
        private void resetDirtyRect(float eventX, float eventY) 
        {
            // The lastTouchX and lastTouchY were set when the ACTION_DOWN
            // motion event occurred.
            dirtyRect.left = Math.min(lastTouchX, eventX);
            dirtyRect.right = Math.max(lastTouchX, eventX);
            dirtyRect.top = Math.min(lastTouchY, eventY);
            dirtyRect.bottom = Math.max(lastTouchY, eventY);
        }
    }
}

推荐答案

我刚刚发现这个链接。可能它会帮助你。尝试实现它。看来这就是你想要的。

I just found this link. May be possible it'll help you. Try to implement it. It seems this is, what you want.

http://www.blogosfera.co.uk/2013/03/how-to-draw-a-path-with-variable-stroke-width/

有关管理路径的统一的图纸检查以下链接:

For Managing uniform Drawing of path check the following link:

<一个href="http://stackoverflow.com/questions/8287949/android-how-to-draw-a-smooth-line-following-your-finger/8289516#8289516">Android如何画一个流畅的线条下手指

希望这会有所帮助。

这篇关于如何绘制路径与帆布可变宽度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆