Javascript 如何在WebView中绘制画布?
我正在制作一个应用程序,人们可以在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()。 不幸的是,新的问题出现了——当我画圆时,它画
LongClick
上画一个圆圈,唯一的问题是当我改变比例(缩放)时,圆圈从原来的位置移动了。在卡拉ok的帮助下,我通过添加scale
floatCanvas.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);
}
}