Javascript 如何在WebView中绘制画布?

Javascript 如何在WebView中绘制画布?,javascript,android,canvas,webview,android-webview,Javascript,Android,Canvas,Webview,Android Webview,我正在制作一个应用程序,人们可以在WebView中放置圆圈。那么,我的 算法是: 检测长点击 在WebView上获取手指坐标 在画布上画圆圈 所以,起初我能够编写一个代码,在LongClick上画一个圆圈,唯一的问题是当我改变比例(缩放)时,圆圈从原来的位置移动了。在卡拉ok的帮助下,我通过添加scalefloatCanvas.drawCircle(x*scale,y*scale,10,p),解决了这个移动问题,其中scale=getScale()。 不幸的是,新的问题出现了——当我画圆时,它画

我正在制作一个应用程序,人们可以在WebView中放置圆圈。那么,我的 算法是:

  • 检测长点击
  • 在WebView上获取手指坐标
  • 在画布上画圆圈
  • 所以,起初我能够编写一个代码,在
    LongClick
    上画一个圆圈,唯一的问题是当我改变比例(缩放)时,圆圈从原来的位置移动了。在卡拉ok的帮助下,我通过添加
    scale
    float
    Canvas.drawCircle(x*scale,y*scale,10,p)
    ,解决了这个移动问题,其中
    scale=getScale()
    。 不幸的是,新的问题出现了——当我画圆时,它画的坐标是错误的。此图显示了我的意思:

    }

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

    如果你知道如何做到这一点或知道一个好的教程-这将是非常感谢

    [更新karaokyo的答案]

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


    要解决圆移动问题,必须根据网络视图的缩放比例调整坐标。对于长按,设置一个
    手势检测器
    ,该检测器保存单击位置和当前比例
    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);
        }
    }
    

    我尝试使用您的解决方案-请参阅更新的问题以获取图像。虽然圆圈不再移动,但它位于错误的位置,再加上getScale()已弃用。WebView中的比例为0.66988,对,您只是根据它之前的位置任意确定它位于错误的位置。如果你想把它放在和以前一样的地方,你必须考虑一个初始比例因子。如果您对
    getScale
    弃用提出质疑,另一种选择是使用自定义
    WebViewClient
    ,它覆盖
    onScaleChanged
    ,并设置一些字段变量“scale”,用于
    onDraw
    。我有自定义
    WebView
    ,但不确定它是否与
    WebViewClient
    相同。您还谈到了初始规模,我应该如何处理它?我指的是通过
    WebView.setWebViewClient
    设置的客户端。人们一直说它不可靠,所以我没有弄糟它。我认为你最好用javascript画圆圈。
    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);
        }
    }