【问题标题】:Display a canvas in a webview在 web 视图中显示画布
【发布时间】:2015-06-23 19:04:44
【问题描述】:

我制作了一个允许绘制函数的 javascript 项目。我想将它集成到 webview 中。我的问题是只有画布没有显示。

这是我的活动代码以及我的 js 和 html 文件

`public class Graphe 扩展 FragmentActivity {

@InjectView( R.id.webview)
 WebView webview;

public class WebAppInterface {
    private Context context;

    public WebAppInterface(Context context) {
        this.context = context;
    }
    @JavascriptInterface
    public String loadData() {
     return new Gson().toJson(context);
    }


}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_graphe);
    ButterKnife.inject(this);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void onResume() {
    super.onResume();

    final WebSettings ws = webview.getSettings();
    ws.setJavaScriptEnabled(true);
    ws.setPluginState(WebSettings.PluginState.ON);
    ws.setAllowFileAccess(true);
    ws.setDomStorageEnabled(true);
    ws.setAllowContentAccess(true);
    ws.setAllowFileAccessFromFileURLs(true);
    ws.setAllowUniversalAccessFromFileURLs(true);
    webview.setWebViewClient(new WebViewClient());
    webview.setWebChromeClient(new WebChromeClient());
    webview.addJavascriptInterface(new WebAppInterface(this), "Android");
    webview.loadUrl("file:///android_asset/Plotter/site.html");
}


public void onBackPressed (){
    Intent back= new Intent(this, MainActivity.class);
    finish();
    startActivity(back);

};

var can = $("#can")[0];
var ctx = can.getContext("2d");
var STAGE = {
	WIDTH: 800,
	HEIGHT: 500
};
var fPoints = [];
var fdPoints = [];
var data = = JSON.parse(Android.loadData());;
var cursor = {x: 0, y: 0};
var VIEW = {
	X: -20,
	Y: -12,
	WIDTH: 40,
	HEIGHT: 25
};
var LQ = 3000;
var vp;
var flags = {};

var f = function(x){
	return 1/x + 4/x;
}

function translate(x, y){
	y = (VIEW.HEIGHT - y + VIEW.Y) * STAGE.HEIGHT / VIEW.HEIGHT;
	x = (x - VIEW.X) * STAGE.WIDTH / VIEW.WIDTH;

	return {
		x: x,
		y: y
	};
}

function translateBack(x, y){
	y = -1 * y * VIEW.HEIGHT / STAGE.HEIGHT - VIEW.HEIGHT - VIEW.Y;
	x = x * VIEW.WIDTH / STAGE.WIDTH + VIEW.X;

	return {
		x: x,
		y: y
	};
}


function calculate(callback){
	fPoints = [];
	fdPoints = [];
	var lastX = null;
	var lastY = null;
	var lastm = null;
	var upperBorder = VIEW.WIDTH + VIEW.X;
	var add = VIEW.WIDTH / LQ;

	for (var x = VIEW.X - (VIEW.WIDTH / STAGE.WIDTH * 10); x < upperBorder; x += add) {
		var y = 0;
		var innerX = x;
		try{
			y = callback.call(this, innerX);
		}
		catch(ex){
			y = 0;
		}

		//--> only draw new line when "m" is different
		if(lastX !== null && lastY !== null){
			if(lastm !== null){
				var curm = (y-lastY) / (innerX - lastX);
				if(curm === lastm){
					var _tmp = fPoints[fPoints.length - 1];
					_tmp.x = innerX;
					_tmp.y = y;
				}
				else{
					fPoints.push({x: innerX, y: y});
				}

				fdPoints.push({x: innerX, y: lastm});
				lastm = curm;
			}
			else{
				lastm = (y-lastY) / (innerX - lastX);
				fPoints.push({x: innerX, y: y});
			}
		}
		else{
			fPoints.push({x: innerX, y: y});
		}
		
		lastX = innerX;
		lastY = y;
	};

	//console.log("added " + (fPoints.length - 1) + " lines.");
}

function calculateArea(callback, x){
	var s = x * VIEW.WIDTH / STAGE.WIDTH / 50;
	var field = 0;
	var m = x < 0 ? -1 : 1;

	for (var i = s * m; Math.abs(i) < Math.abs(x); i += s * m) {
		field += s * callback(i);
	};

	return field;
}

function calculateTangens(callback, x){
	var x1 = x - VIEW.WIDTH / 1000;
	var x2 = x + VIEW.WIDTH / 1000;

	var y1 = callback(x1);
	var y2 = callback(x2);

	var m = (y1 - y2) / (x1 - x2);

	return {
		m: m,
		b: y1 - m * x1
	};
}

function parseInfix(){
	var postfix = new Postfix($("#infix").val());
	var callback = postfix.generateCallback(postfix);
	f = callback;
	calculate(f);
}

/* * * * * * * * * * * Initialize * * * * * * * * * * */

function init(){
	can.width = STAGE.WIDTH;
	can.height = STAGE.HEIGHT;

	can.style.width = STAGE.WIDTH + "px";
	can.style.height = STAGE.HEIGHT + "px";

	ctx.shadowBlur = 5;
	ctx.shadowColor = "black";
	ctx.lineJoin = ctx.lineCap = 'round';

	$("#infix").val("e^x");

	//check url
	if(document.URL.indexOf("#") !== -1){
		var splitted = document.URL.split("#");
		if(splitted[1].trim().length !== 0){
			$("#infix").val(splitted[1].trim());
		}
	}

	parseInfix();

	//Input flags
	var leftPressed = false; // false, or xy object
	var newVIEW = {
		X: VIEW.X,
		Y: VIEW.Y,
		WIDTH: VIEW.WIDTH,
		HEIGHT: VIEW.HEIGHT
	};

	//Animation rendering
	var animationRender = function(){
		var zoomSpeed = 30;

		VIEW.X += (newVIEW.X - VIEW.X) / 100 * zoomSpeed;
		VIEW.Y += (newVIEW.Y - VIEW.Y) / 100 * zoomSpeed;
		VIEW.WIDTH += (newVIEW.WIDTH - VIEW.WIDTH) / 100 * zoomSpeed;
		VIEW.HEIGHT += (newVIEW.HEIGHT - VIEW.HEIGHT) / 100 * zoomSpeed;

		window.requestAnimationFrame(animationRender);
	};

	window.requestAnimationFrame(animationRender);

	//Flag check loop
	var flagCheckLoop = function(){
		if(flags.btnToOrigin === true){
			$("body").css("cursor", "pointer");
		}
		else{
			$("body").css("cursor", "default");
		}

		window.setTimeout(flagCheckLoop, 50);
	};
	window.setTimeout(flagCheckLoop, 50);

	//recalculate every n seconds
	var calculateLoop = function(){
		calculate(f);

		window.setTimeout(calculateLoop, 500);
	};
	window.setTimeout(calculateLoop, 500);

	$(can).mousemove(function(e){
		cursor.x = (e.offsetX || e.clientX - $(e.target).offset().left);
		cursor.y = (e.offsetY || e.clientY - $(e.target).offset().top);

		if(leftPressed !== false){
			var moveX = VIEW.WIDTH / STAGE.WIDTH * (leftPressed.x - cursor.x);
			var moveY = VIEW.HEIGHT / STAGE.HEIGHT * (leftPressed.y - cursor.y);

			newVIEW.X += moveX;
			newVIEW.Y -= moveY;
			leftPressed = {x: cursor.x, y: cursor.y};

			
		}
	})
	.mousedown(function(e){
		cursor.x = (e.offsetX || e.clientX - $(e.target).offset().left);
		cursor.y = (e.offsetY || e.clientY - $(e.target).offset().top);
		leftPressed = {x: cursor.x, y: cursor.y};

		if(flags.btnToOrigin === true){
			newVIEW.X = -VIEW.WIDTH / 2;
			newVIEW.Y = -VIEW.HEIGHT / 2;
		}
	})
	.mousewheel(function(e){
		e.preventDefault();

		var zx = VIEW.WIDTH / 10;
		var zy = VIEW.HEIGHT / 10;

		newVIEW.X += zx * (cursor.x / STAGE.WIDTH) * e.deltaY;
		newVIEW.WIDTH -= zx * e.deltaY;

		newVIEW.Y -= zy * (cursor.y / STAGE.HEIGHT) * e.deltaY;
		newVIEW.HEIGHT += zy * e.deltaY;

		calculate(f);

		return false;
	});

	$(document).mouseup(function(e){
		cursor.x = (e.offsetX || e.clientX - $(e.target).offset().left);
		cursor.y = (e.offsetY || e.clientY - $(e.target).offset().top);
		leftPressed = false;

		calculate(f);
	});

	$("#do").click(function(){
		parseInfix();
	});

	$("#infix").keyup(function(){
		window.location.hash = $("#infix").val();
	});
}

init();


/* * * * * * * * * * * Render * * * * * * * * * * */

function render(){
	window.requestAnimationFrame(render);

	can.width = can.width;
	var xcoord = translate(0,0);
	vp = translateBack(cursor.x, cursor.y);
	var tan = calculateTangens(f, vp.x);

	//draw axis
	ctx.beginPath();
	//X
	ctx.moveTo(0,translate(0, 0).y);
	ctx.lineTo(STAGE.WIDTH,translate(0, 0).y);
	//Y
	ctx.moveTo(translate(0, 0).x, 0);
	ctx.lineTo(translate(0, 0).x, STAGE.HEIGHT);
	ctx.lineWidth = 1;
	ctx.stroke();


	//cursor field to y
	ctx.beginPath();
	var s = vp.x < 0 ? -1 : 1;
	s *= VIEW.WIDTH / STAGE.WIDTH * 3;
	for (var i = 0; Math.abs(i) < Math.abs(vp.x); i += s) {
		var vx = translate(i, f(i));
		ctx.moveTo(vx.x, xcoord.y);
		ctx.lineTo(vx.x, vx.y);
	};

	ctx.shadowBlur = 0;
	ctx.strokeStyle = "rgba(150,150,200,0.5)";
	ctx.stroke();


	//Cursor
	ctx.beginPath();
	ctx.moveTo(cursor.x, 0);
	ctx.lineTo(cursor.x, STAGE.HEIGHT);
	ctx.moveTo(0, cursor.y);
	ctx.lineTo(STAGE.WIDTH, cursor.y);

	ctx.lineWidth = 1;
	ctx.setLineDash([2]);
	ctx.shadowBlur = 0;
	ctx.strokeStyle = "rgb(150,150,255)";
	ctx.stroke();


	ctx.beginPath();
	ctx.moveTo(cursor.x, xcoord.y);
	ctx.lineTo(cursor.x, translate(0,f(vp.x)).y);
	ctx.strokeStyle = "rgb(100,100,255)";
	ctx.lineWidth = 2;
	ctx.shadowBlur = 0;
	ctx.setLineDash([])
	ctx.stroke();



	//plot
	if(fPoints.length > 0){
		ctx.beginPath();
		for (var i = 0, l = fPoints.length; i < l; i++) {
			var p = translate(fPoints[i].x,fPoints[i].y);
			
			if(p.y >= -10000 && p.y <= 10000){
				if(i===0)
					ctx.moveTo(p.x, p.y);
				else
					ctx.lineTo(p.x, p.y);
			}
		};
		
		ctx.lineWidth = 2;
		ctx.shadowBlur = 2;
		ctx.shadowColor = "black";
		ctx.strokeStyle = "black";
		ctx.stroke();
	}


	

	
	//Draw data
	data.fy = f(vp.x);
	data.fx = vp.x;
	//data.Fx = calculateArea(f, vp.x);
	data.tm = tan.m;
	data.tb = tan.b;

	
	//draw icons -->
	//
	var opacity = 0.5;
	var size = 30;
	var cursorIn1 = 
		cursor.x >= STAGE.WIDTH - 10 - size && cursor.x <= STAGE.WIDTH - 10 &&
		cursor.y >= 10 && cursor.y <= 10 + size;

	if(cursorIn1){
		ctx.strokeStyle = "rgba(0,0,255, 0.8)";
		flags.btnToOrigin = true;
	}
	else{
		ctx.strokeStyle = "rgba(0,0,255, 0.5)";
		flags.btnToOrigin = false;
	}

	ctx.beginPath();
	ctx.moveTo(STAGE.WIDTH - size / 2 - 10, 10);
	ctx.lineTo(STAGE.WIDTH - size / 2 - 10, 10 + size);

	ctx.moveTo(STAGE.WIDTH - size - 10, size/2 + 10);
	ctx.lineTo(STAGE.WIDTH - 10, size/2 + 10);
	ctx.stroke();

	ctx.beginPath();
	ctx.arc(
		STAGE.WIDTH - size / 2 - 10, 
		size/2 + 10,
		size / 4,
		0,
		2*Math.PI);
	ctx.arc(
		STAGE.WIDTH - size / 2 - 10, 
		size/2 + 10,
		size / 8,
		0,
		2*Math.PI);
	ctx.stroke();
}

render();


/* * * * * * * * * * * Data - Render * * * * * * * * * * */

function niceRound(num, digits){

	var p = Math.pow(10, digits);
	var s = "" + (Math.round(num * p) / p);
	if(s.indexOf(".") === -1){
		return num;
	}

	var cpart = s.split(".")[1].length;

	for(var i=0;i<digits - cpart;i++){
		s += "0";
	}

	return s;
}

function dataRender(){
	var round = 3;

	$(".fx").text(niceRound(data.fx, round));
	$(".fy").text(niceRound(data.fy, round));
	$(".Fy").text(niceRound(data.Fx, round));
	$(".tm").text(niceRound(data.tm, round));
	$(".tb").text(niceRound(data.tb, round));

	window.setTimeout(dataRender, 100);
}

dataRender();

<!DOCTYPE html>
<html>
<head>
	<title>plot</title>
	<link rel="stylesheet" type="text/css" href="style.css" />
	<meta name="keywords" content="plot,2D,function,f(x)" />
	<meta name="description" content="Plots a function" />
	<meta name="viewport" content = "width = device-width, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, user-scalable = no" />

</head>
<body>
	<div -webkit-class="canvas-holder">
		<form action="#" onsubmit="return false;">
			<table cellspacing="0" cellpadding="0" class="infix-box">
				<tr>
					<td>
						<input class="input-formula" type="text" placeholder="infix" id="infix" />
					</td>
					<td -webkit-style="width: 120px;text-align: right;">
						<input -webkit-id="do" type="submit" value="Plot" />
					</td>
				</tr>
				
			</table>
		</form>
		
		

		<canvas id="can"> </canvas>

		<div -webkit-id="dataBox">
			<table>
				<tr>
					<th>
						f(<span class="fx"></span>)
					</th>
					<td>
						<span class="fy"></span>
					</td>
				</tr>
				
			</table>
		</div>
	</div>
	


	<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
	<script type="text/javascript" src="jquery.mousewheel.min.js"></script>
	<script type="text/javascript" src="postfix.js"></script>
	<script type="text/javascript" src="script.js"></script>
	<script type="text/javascript">
	$("#short").click(function(){
		var postfix = new Postfix($("#infix").val());
		$("#postfix").val(postfix.postfix.join(" "));
	});
	</script>
</body>
</html>

请帮忙!!

【问题讨论】:

    标签: javascript android canvas android-studio webview


    【解决方案1】:

    试试这个代码:

    webview.loadDataWithBaseURL("file:///android_asset/Plotter/site.html", "", "text/html", "UTF-8", "");
    

    改为

    webview.loadUrl("file:///android_asset/Plotter/site.html");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-26
      • 2015-12-02
      • 2023-03-18
      • 1970-01-01
      • 2013-06-08
      • 1970-01-01
      相关资源
      最近更新 更多