How to draw path with variable width in canvas

前端 未结 5 1014
猫巷女王i
猫巷女王i 2020-12-03 20:36

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

But now our requirement is

相关标签:
5条回答
  • 2020-12-03 20:49

    You can use getPressure() method and combine it with this answer https://stackoverflow.com/a/15533607/1112882 to make it work. Idea is to keep storing widths and using it.

    0 讨论(0)
  • 2020-12-03 20:49
    @Override
        protected synchronized void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            this.canvas = canvas;
            Log.d("tag", "Padding" + padding);
            int newPadding = (int) padding;
    
            // Set Min X
            int xPadding = (int) padding;
            Paint bottomLeftTextPaint = new Paint();
            Typeface tf = Typeface.create("Helvetica", Typeface.NORMAL);
            bottomLeftTextPaint.setColor(context.getResources().getColor(
                    R.color.common_color_rangeseekbar_bottomtext));
            bottomLeftTextPaint.setTextAlign(Align.LEFT);
            bottomLeftTextPaint.setTypeface(tf);
            bottomLeftTextPaint.setTextSize(20);
    
            bottomLeftTextPaint.setColor(context.getResources().getColor(
                    R.color.common_color_rangeseekbar_bottomtext));
            canvas.drawText(absoluteMinValue + "", newPadding - 5,
                    0.5f * (getHeight() + lineHeight) + 30, bottomLeftTextPaint);
            // draw seek bar background line
            final RectF rect = new RectF(newPadding - 5,
                    0.5f * (getHeight() - lineHeight), getWidth() - padding,
                    0.5f * (getHeight() + lineHeight));
            paint.setStyle(Style.FILL);
            // paint.setColor(Color.parseColor("#ED797F"));
            paint.setColor(Color.parseColor("#e2e2e2"));
            paint.setAntiAlias(true);
            canvas.drawRect(rect, paint);
            RectF rectStartLine = new RectF(newPadding - 5,
                    0.5f * (getHeight() - lineHeight) - 5, padding,
                    0.5f * (getHeight() + lineHeight) + 5);
            paint.setStyle(Style.FILL);
            paint.setColor(Color.BLACK);
            paint.setAntiAlias(true);
            canvas.drawRect(rectStartLine, paint);
            // End Line
            // RectF rectEndLine = new RectF(getWidth() - padding,
            // 0.5f * (getHeight() - lineHeight) - 5,
            // getWidth() - padding + 5, 0.5f * (getHeight() + lineHeight) + 5);
            RectF rectEndLine = new RectF(getWidth() - padding,
                    0.5f * (getHeight() - lineHeight) - 5,
                    getWidth() - padding + 5, 0.5f * (getHeight() + lineHeight) + 5);
            paint.setStyle(Style.FILL);
            paint.setColor(Color.BLACK);
            paint.setAntiAlias(true);
            canvas.drawRect(rectEndLine, paint);
            // End Text
            // Set Min X
            int xEndPadding = (int) padding;
    
            paint.setColor(Color.parseColor(context.getResources().getString(
                    R.color.common_color_rangeseekbar_bottomtext)));
            paint.setTextSize(20);
            int max = (Integer) absoluteMaxValue;
            String MaxValue = String.valueOf(max);
            paint.setColor(Color.parseColor(context.getResources().getString(
                    R.color.common_color_rangeseekbar_bottomtext)));
            Paint bottomTextPaint = new Paint();
            bottomTextPaint.setTypeface(tf);
            bottomTextPaint.setColor(context.getResources().getColor(
                    R.color.common_color_rangeseekbar_bottomtext));
            bottomTextPaint.setTextAlign(Align.RIGHT);
            bottomTextPaint.setTypeface(tf);
            bottomTextPaint.setTextSize(20);
            // if (MaxValue.length() > 4) {
            //
            // canvas.drawText(absoluteMaxValue + "", getWidth() - padding - 23,
            // 0.5f * (getHeight() + lineHeight) + 30, bottomTextPaint);
            // } else if (MaxValue.length() > 3) {
            // canvas.drawText(absoluteMaxValue + "", getWidth() - padding - 18,
            // 0.5f * (getHeight() + lineHeight) + 30, bottomTextPaint);
            // } else if (MaxValue.length() > 2) {
            // canvas.drawText(absoluteMaxValue + "", getWidth() - padding - 13,
            // 0.5f * (getHeight() + lineHeight) + 30, bottomTextPaint);
            // } else {
            canvas.drawText(absoluteMaxValue + "", getWidth() - padding,
                    0.5f * (getHeight() + lineHeight) + 30, bottomTextPaint);
            // }
            // draw seek bar active range line
            rect.left = normalizedToScreen(normalizedMinValue);
            rect.right = normalizedToScreen(normalizedMaxValue);
    
            // orange color
            paint.setColor(DEFAULT_COLOR);
            paint.setTypeface(tf);
    
            canvas.drawRect(rect, paint);
            Paint headerPaint = new Paint();
            // Set TextSize
            headerPaint.setTextSize(20);
            headerPaint.setTextAlign(Align.LEFT);
            headerPaint.setTypeface(tf);
            headerPaint.setColor(Color.parseColor(context.getResources().getString(
                    R.color.common_color_rangeseekbar_toptext)));
            headerPaint.setTextAlign(Align.LEFT);
            // draw minimum thumb
            drawThumb(normalizedToScreen(normalizedMinValue),
                    Thumb.MIN.equals(pressedThumb), canvas);
            canvas.drawText("" + getSelectedMinValue(),
                    normalizedToScreen(normalizedMinValue)-5,
                    (float) ((0.5f * getHeight()) - thumbHalfHeight) - 8,
                    headerPaint);
            // draw maximum thumb
            drawThumb(normalizedToScreen(normalizedMaxValue),
                    Thumb.MAX.equals(pressedThumb), canvas);
            // Right TrackText
            Paint righText = new Paint();
            righText.setTextAlign(Align.RIGHT);
            righText.setAntiAlias(true);
            righText.setTextSize(20);
            righText.setTypeface(tf);
            canvas.drawText("" + getSelectedMaxValue(),
                    normalizedToScreen(normalizedMaxValue),
                    (float) ((0.5f * getHeight()) - thumbHalfHeight) , righText);
        }
    
    0 讨论(0)
  • 2020-12-03 21:03

    Path does not support variable width drawing.

    You can get the touch pressure and velocity using MotionEvent.getPressure() and VelocityTracker.computeCurrentVelocity() methods.

    Next, you need to create a function to map a particular velocity or pressure to a certain width.

    Assuming you have these ready, One way to draw variable width paths would be to divide a path into multiple paths each of a different width. For instance, if width needs to progress from 10 to 50 over the course of a single path, you can have 10 paths instead of width 5,10,15,20... and so on. You will have to do a lot of optimization as creating a large number of Path objects will lead to memory consumption.

    Another way is to use quad-curves or bezier curves.

    0 讨论(0)
  • 2020-12-03 21:06

    Maybe this will help you, had to implement one myself.

    0 讨论(0)
  • 2020-12-03 21:12

    Update: Thanks to Raghunandan and M-WaJeEh.

    I was wrong. You can refer to this SO question.

    android find pressure on screen

    And the other link in the comments section.

    http://developer.android.com/reference/android/view/MotionEvent.html#getPressure(int)

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