如何在WebView中绘制Canvas?

时间:2015-08-11 18:34:41

标签: javascript android canvas webview android-webview

我正在创建一个应用程序,人们可以在WebView中放置圆圈。所以我的 算法是:

  1. 长按检测
  2. 在WebView上获取手指坐标
  3. 在Canvas中绘制圆圈
  4. 所以起初我能够编写一个在LongClick上绘制圆圈的代码,唯一的问题是当我改变比例(缩放)时,圆圈从它的位置移开。在karaokyo回答的帮助下,我已经解决了这个动人的问题)添加scale float Canvas.drawCircle(x * scale, y * scale, 10, p),其中scale = getScale()。 不幸的是,出现了新问题 - 当我制作圆圈时,它会绘制错误的坐标。这张图片显示了我的意思: enter image description here

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

    }

    此外,如果我多次双击圆圈(两者)出现在错误的位置,请在我点击时移动到正确的位置。

    enter image description here

    如果您知道如何做或知道一个好的教程 - 我将非常感激。

    [更新karaokyo&#39的答案]

    我已经复制了你的代码,但是圈子仍然在错误的地方,事实上,initialScale值是2.0。在这张图片上可以清楚地看到。 1.具有移动问题的圆,但坐标正确。 2.圆圈没有移动问题,坐标乘以scale = getScale。 3.圆圈没有移动问题,坐标乘以scale/initScale

    enter image description here

1 个答案:

答案 0 :(得分:1)

要解决圆圈移动问题,您必须根据WebView的缩放比例调整坐标。如需长按,请设置GestureDetector,以保存要在onLongPress中使用的点击位置和当前比例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);
    }
}