|
蓝森林 http://www.lslnet.com 2006年8月25日 8:28
Js在页面画一个圆的思考
基于上一篇日志(http://redhacker.blueidea.com/archives/2006/1342.shtml)的思考,我试图用js在页面画了一个圆,当然js好象有自己的图形类库(我只见过,用js做星际争霸的游戏,还有在csdn见过用js画圆,好象是js自带的图形函数库)。
原理:
1.数学中圆坐标为:(x-x0)^2+(y-y0)^2=r^2这个公式,其中(x0,y0)为圆心坐标,x,y为变量和自变量。
2.在网页中<div>标签在页面中的位置具有坐标的概念。
代码运行:
[html]
<script>
//code by redhacker
function drawCircle(r){
var x0 = screen.width/2;//圆心纵坐标
var y0 = screen.height/2;//圆心横坐标
var r0 = Number(r);//半径
var x1 = x0-r0;
var x2 = x0+r0;
var x,y;
document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
for(var i=x1;i<=x2;i++){
x = i;
y = Math.sqrt(Math.pow(r0,2) - Math.pow(x - x0,2)) + y0;
document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
}
for(var i=x2;i>=x1;i--){
x = i;
y = -Math.sqrt(Math.pow(r0,2) - Math.pow(x - x0,2)) + y0;
document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
}
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html]
思考:
1.使用三角函数作为变量,则可以画出非常均匀的圆来,回头做,你也试试?;-)
2.使用勾股定理画个三角形行的通吗?
原文地址:http://redhacker.blueidea.com/archives/2006/1346.shtml |
js画几何图形我以前也捣鼓过,还整出过一个画图板,简单的几何图形、直线、曲线、填充等功能也都有,大致思路是用表格,分割成很小的单元格,这些单元格就是基本的像素,画画线条还好,但是大面积填充不规则几何图形的时候,用了递归,所以经常造成堆栈溢出。总的来说,用js做图形意义不大,js本身的效率再加上web端缓慢的渲染,那是很无趣的尝试。至于所谓的js图形类库,好像没见过。 |
搜了一下,竟然还能找到最初的一些东西。
[html]
<html>
<head>
</head>
<body style="cursor:hand">
<br/><br/>
<table align="center">
<tr>
<td align="center">
<input type="button" value="点" onclick="draw_Type='Point';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='点'">
<input type="button" value="线段" onclick="draw_Type='Line';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='线段'">
<input type="button" value="连续线段" onclick="draw_Type='c_Line';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='连续线段'">
<input type="button" value="圆" onclick="draw_Type='Circle';firstP_R=firstP_C=secondP_R=secondP_C=-1;window.viewsource.value='圆'">
<select onchange="default_Color=this.value">
<option value="green">绿色</option>
<option value="black">黑色</option>
<option value="red">红色</option>
<option value="blue">兰色</option>
<option value="yellow">黄色</option>
</select>
</td>
</tr>
</table>
<script language="javascript">
var draw_Type = "Line";
var firstP_R=firstP_C=secondP_R=secondP_C=-1;
var distance;
var r_Index,c_Index;
var srcE;
var default_Color = "green";
function main_F(){
srcE = event.srcElement;
if(srcE.type != "button" && srcE.type != "select-one" && srcE.type != "text"){
if(firstP_R == -1){
firstP_R = event.x;
firstP_C = event.y;
draw_Point(firstP_R,firstP_C,default_Color);
return false;
}else{
secondP_R = event.x;
secondP_C = event.y;
draw_Point(secondP_R,secondP_C,default_Color);
distance = Math.sqrt((firstP_R-secondP_R)*(firstP_R-secondP_R)+(firstP_C-secondP_C)*(firstP_C-secondP_C));
}
}else{
return false;
}
if(draw_Type == "Point"){
draw_Point(event.x,event.y,default_Color);
}else if(draw_Type == "Circle"){
//画圆
draw_Circle();
firstP_R=firstP_C=secondP_R=secondP_C=-1;
}else if(draw_Type == "Line"){
//画单根直线
draw_Line();
firstP_R=firstP_C=secondP_R=secondP_C=-1;
}else if(draw_Type == "c_Line"){
//画连续直线
draw_Line();
firstP_R = secondP_R;
firstP_C = secondP_C;
secondP_R=secondP_C=-1;
}else if(draw_Type == ""){
window.viewsource.value="请重新选择操作!!!!!!!!!";
}
}
function draw_Point(x,y,color){
var newObj=document.createElement("IMG");
document.body.appendChild(newObj);
with(newObj){
border=0;
style.position='absolute';
style.pixelLeft=(x);
style.pixelTop=(y);
style.backgroundColor=color;
style.pixelWidth=1;
style.pixelHeight=1;
}
}
function draw_Line(){
r_Index = (firstP_R-secondP_R)/distance;
c_Index = (firstP_C-secondP_C)/distance;
for(var i=0;i<distance;i++){
draw_Point(firstP_R-=r_Index,firstP_C-=c_Index,default_Color);
}
}
function draw_Circle(){
//for循环里的步距和步长有待选择更优化的算法和数值
r_Index = c_Index = 1/distance;
for(var i=0;i<=6.2832;i+=r_Index){
exc_x=Math.sin(i)*distance;
exc_y=Math.cos(i)*distance;
draw_Point(firstP_R+exc_x,firstP_C+exc_y,default_Color);
}
}
function move_F(){
if(event.button==1){
window.viewsource.value="任意线形";
draw_Type="";
draw_Point(event.clientX,event.clientY,default_Color);
}
return false;
}
document.onclick = main_F;
//document.onmousemove = move_F;
</script>
<br><br><br><br>
<textarea name="viewsource" readonly rows="10" cols="80">线段</textarea>
</body>
</html>
[/html] |
其实很久以前我就问过这个问题,我佛山人做过答,刚找了一下找到了,是用三角函数写的
http://bbs.blueidea.com/viewthread.php?tid=1181877 |
[html]
<script>
//code by redhacker
function drawCircle(r){
var x0 = screen.width/2;//圆心纵坐标
var y0 = screen.height/2;//圆心横坐标
var r0 = Number(r);//半径
var angle = 2*Math.PI/1000
var x,y;
var i=0
document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
while(i<=2*Math.PI){
x = x0 + r0*Math.cos(i);
y = x0 + r0*Math.sin(i);
document.write("<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>");
i = i+angle;
}
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html] |
楼上的算法无论从精确程度还是效率上都......
现改进如下:
[html]
<script>
var points=new Array();
//code by redhacker
//edited by shouhaimu
function drawCircle(r){
var x0 = screen.width/2;//圆心纵坐标
var y0 = screen.height/2;//圆心横坐标
var c0 = 2*Math.PI*r;
var x,y;
var i=0
document.write("<div style=\"position:absolute;left:"+ x0 +"px;top:500px;color: #FF0000\"><h2>Draw Circle Demo</h2></div>");
while(i<=c0){
x = Math.round(x0 + r*Math.cos(i/r));
y = Math.round(x0 + r*Math.sin(i/r));
points[i]="<div style=\"position:absolute;left:"+ x +"px;top:"+ y +"px;color: #FF0000\">.</div>";
i = i+1;
}
document.write(points.join(''));
}
</script>
<input name="radii" type="text" id="radii" value="100" size="10" />
<input type="submit" name="Submit" value="画圆" onclick="drawCircle(document.getElementById('radii').value)"/>
[/html]
|
bjhaoyun在上个帖子中说
的确精确不少:D |
|