简体   繁体   中英

How to draw Canvas in WebView?

I'm making an app where people will be able to place circles in WebView. So, my algorithm is:

  1. Detect long click
  2. Get finger coordinates on WebView
  3. Draw circle in Canvas

So at first I was able to write a code that would draw a circle on LongClick , the only problem was that when I changed scale(zoomed), circle moved from it's place. With the help of karaokyo answer I have fixed this moving issue) with adding scale float Canvas.drawCircle(x * scale, y * scale, 10, p) , where scale = getScale() . Unfortunately new problem appeared - when I make the circle it draws in wrong coordinates. This image shows what I mean: 在此处输入图片说明

public DrawWebView (Context context, AttributeSet attrs)
{
    super (context, attrs);
    wv1 = (DrawWebView) findViewById(R.id.webView1);
    wv1.loadUrl("file://" + Environment.getExternalStorageDirectory() + "/Pictures/ScolDetectPics/boxes.jpg");
    wv1.getSettings().setBuiltInZoomControls(true);
    wv1.getSettings().setDisplayZoomControls(false);
    wv1.getSettings().setSupportZoom(true);
    wv1.getSettings().setUseWideViewPort(true);
    wv1.getSettings().setLoadWithOverviewMode(true); 
    wv1.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
    mContext = context;





public boolean onTouch(View v, MotionEvent event) {

    int action = event.getAction(); 


    switch (action) { 
    case MotionEvent.ACTION_DOWN:
        draw = true;
        this.invalidate();
        break;
    case MotionEvent.ACTION_MOVE:   
        this.invalidate();
        break;

    case MotionEvent.ACTION_UP: 
        this.invalidate();
        break;
    case MotionEvent.ACTION_CANCEL:

        break; 

    default: 
        break; 
    }
    return true;
}


@Override
protected void onDraw(Canvas canvas) 
{

    super.onDraw (canvas);
    text = MainActivity.text;

    zoomPos = MainActivity.zoomPos;
    Paint p = new Paint();
    p.setColor (Color.RED);

    if(initScale == 0){
        initScale = getScale();
    }

    float scale = getScale();

    float refScale = scale/initScale;

    if(MainActivity.drawConfirm){
    zoomPos = MainActivity.zoomPos;
    draw1 = true;
    }
    canvas.drawCircle(330 * refScale, 618 * refScale, 10, p);
    //text.setText(Float.toString(scale));
    text.setText(Float.toString(initScale));
    canvas.drawCircle(330, 618, 10, p);
    if(draw1){
    canvas.drawCircle(zoomPos.x * refScale, zoomPos.y * refScale, 10, p);
    }

}

}

Also if I double-tap multiple times circles(both) appear in wrong place, move to the right place when I click.

在此处输入图片说明

If you know how to do this or know a good tutorial - it would be much appreciated.

[Update for karaokyo's answer]

I've copied your code, but circle's still in the wrong place, in fact, initialScale value is 2.0. It is clearly seen on this image. 1. Circle that has moving issue, but in correct coordinates. 2. Circle without moving issue, coordinates multiplied by scale = getScale . 3. Circle without moving issue, coordinates multiplied by scale/initScale

在此处输入图片说明

To address your circle moving problem, you would have to adjust your coordinates based on the zoom scale of the WebView. For the long press, set up a GestureDetector that saves the click location and current scale onLongPress to be used in your onDraw :

public class DrawWebView extends WebView {
    private GestureDetector mDetector;
    private float mInitialScale;
    private int mX;
    private int mY;

    public DrawWebView(Context context) {
        super(context);
        init();
    }

    public DrawWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DrawWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init(){
        loadUrl("file://" + Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");
        setWebViewClient(new WebViewClient());
        getSettings().setBuiltInZoomControls(true);
        getSettings().setDisplayZoomControls(false);
        getSettings().setSupportZoom(true);
        getSettings().setUseWideViewPort(true);
        getSettings().setLoadWithOverviewMode(true);
        getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

        mDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() {
            @Override
            public boolean onDown(MotionEvent e) {
                return false;
            }

            @Override
            public void onShowPress(MotionEvent e) {

            }

            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return false;
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                return false;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                mX = (int) e.getX() + getScrollX();
                mY = (int) e.getY() + getScrollY();
                mInitialScale = getScale();
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                return false;
            }
        });

        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mDetector.onTouchEvent(event);
            }
        });
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw (canvas);

        float scale = getScale() / mInitialScale;

        Paint p = new Paint();

        p.setColor(Color.RED);
        canvas.drawCircle(mX * scale, mY * scale, 10, p);

        p.setColor(Color.GREEN);
        canvas.drawCircle(mX, mY, 5, p);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM