iT邦幫忙

0

html網頁設計的相關問題

今天有同事突然問我可以在網頁上面任意畫一個梯形圖嗎?
且線條要加粗可以做到嗎?
第二問題就是
可以在上面加一個實心圓點嗎?且一樣加大變粗?
請問一下各位大大html網頁可以做到嗎?
因為小弟大部分都是用表格或DIV比較多
所以我是知道可以這樣做變粗線
但是任意畫圖形線就沒有試過了
可以請教一下各位大大嗎??

看更多先前的討論...收起先前的討論...
wordsmith iT邦高手 1 級 ‧ 2011-05-15 23:19:41 檢舉
做當然是做得到,如果要看範例的話,就是看google docs裡面的繪圖功能,可以插入一個梯形符號,任意變形, 邊框加粗或是改變顏色、底色。

Google是用HTML 5的Canvas技術做到的,另外也可以用flash或是Silverlight這類的技術達到同樣的效果。

不過不管哪一種,都有點技術門檻在,不是一般的HTML就能解決的。
cair03019816提到:
所以基本上不是一般的HTML可以解決嚕~~^^~~那CGI或JAVA可以嗎??
所以基本上不是一般的HTML可以解決嚕~~^^~~那CGI或JAVA可以嗎??
insect iT邦新手 3 級 ‧ 2011-05-16 02:03:16 檢舉
Using complex style sheet (.css), you can put images anywhere in the HTML page. It is very difficult to make it right through all browsers.

You can use CGI, PHP, JAVA, or whatever back-end programming to create these images (at server side). However, these are *NOT* HTML, they are graphic programming (to generate images).
ccutmis iT邦高手 9 級 ‧ 2011-05-16 03:47:47 檢舉
SVG...hope it's useful...
http://zh.wikipedia.org/wiki/SVG
fantsyss iT邦新手 2 級 ‧ 2011-05-16 08:39:46 檢舉
看梯型圖是要怎麼應用,是互動式的嗎,就是說可以直接在瀏覽器的網頁上畫出梯型圖

互動式可能要用到FLASH,Java。

還是圖片式的,要是圖片就直接插入就可。

假如要畫成表格,不插入圖片的話可以試試css唷
我禁不住要想
這位樓主的同事是不是怪怪的
或者
樓主為什麼會被問這些問題疑惑

既然一直都有問到答案
我很期待後續
他同事還會問出什麼問題失神
因為很簡單我的工作環境很多都是用電腦在執行的,當然嚕科技始終來自於人性,所以就會有很多好朋友們會一直提問題,但畢竟很多東西不是很多懂,所以就會請教各位大大,不恥下問才會學到很多東西的。
感謝您不恥下問囧
fillano iT邦超人 1 級 ‧ 2011-05-17 22:04:17 檢舉
等到累積了一些功力,自己動手做會比不恥下問可以學到更多哈哈
idoncys iT邦新手 3 級 ‧ 2011-05-17 22:56:11 檢舉
http://raphaeljs.com/
我都是使用這個javascript library,向量繪圖功能強大,使用上也簡單.也可對每個物件加事件處理.
16
aliceyeh
iT邦新手 2 級 ‧ 2011-05-16 09:24:23
最佳解答

用 html5 Canvas 可以輕易達到這個功能

12
alexlin6194
iT邦新手 2 級 ‧ 2011-05-16 09:23:08

html的話是無法做到的.
使用Asp.Net語言的話,可以使用 Drawing.Image元件來畫圖

32
fillano
iT邦超人 1 級 ‧ 2011-05-16 09:51:21

提供一個另類的作法,用div去模擬一個長寬各1 pixel的點,然後用來畫圖。

首先需要幾個函數來定義點、畫線、畫多邊形:

<pre class="c" name="code">
function Point (_x, _y) {
	this.x = _x;
	this.y = _y;
}

function getLine (_points) {
	if (_points.length != 2) {
		return false;
	}
	var points = new Array();
	if (Math.abs(_points[1].x-_points[0].x) > Math.abs(_points[1].y-_points[0].y)) {
		var accu = _points[0].y;
		if (_points[1].x > _points[0].x) {
			for (var x = _points[0].x; x < _points[1].x+1; x++) {
				y = Math.floor(accu);
				accu += (_points[1].y - _points[0].y) / (_points[1].x - _points[0].x);
				points.push(new Point(x,y));
			}
		} else if (_points[0].x > _points[1].x) {
			for (var x = _points[0].x; x > _points[1].x-1; x--) {
				y = Math.floor(accu);
				accu -= (_points[1].y - _points[0].y) / (_points[1].x - _points[0].x);
				points.push(new Point(x,y));
			}
		} else {
			if (_points[1].y > _points[0].y) {
				for (var y=_points[0].y; y<_points[1].y+1; y++) {
					points.push(new Point(_points[0].x,y))
				}
			} else {
				for (var y=_points[0].y; y>_points[1].y-1; y--) {
					points.push(new Point(_points[0].x,y))
				}
			}
		}
	} else {
		var accu = _points[0].x;
		if (_points[1].y > _points[0].y) {
			for (var y = _points[0].y; y < _points[1].y+1; y++) {
				x = Math.floor(accu);
				accu += (_points[1].x - _points[0].x) / (_points[1].y - _points[0].y);
				points.push(new Point(x,y));
			}
		} else if (_points[0].y > _points[1].y) {
			for (var y = _points[0].y; y > _points[1].y-1; y--) {
				x = Math.floor(accu);
				accu -= (_points[1].x - _points[0].x) / (_points[1].y - _points[0].y);
				points.push(new Point(x,y));
			}
		} else {
			if (_points[1].x > _points[0].x) {
				for (var x=_points[0].x; x<_points[1].x+1; x++) {
					points.push(new Point(x,_points[0].y))
				}
			} else {
				for (var x=_points[0].x; x>_points[1].x-1; x--) {
					points.push(new Point(x,_points[0].y))
				}
			}
		}
	}
	return points;
}

function getPolygon (_points) {
	if (_points.length < 3) {
		return false;
	}
	var ret = new Array();
	for (var i=0; i<_points.length; i++) {
		if ((i+1) == _points.length) {
			ret = ret.concat(getLine(new Array(_points[i], _points[0])));
			ret.pop();
		} else {
			ret = ret.concat(getLine(new Array(_points[i], _points[i+1])));
			ret.pop();
		}
	}
	return ret;
}
function drawPixels(_points, _color) {
	for (var j=0;j<_points.length; j++) {
		drawPixel(_points[j], _color);
	}
}
function drawPixel(_point, _color) {
	var obj = document.createElement("div");
//	obj.style = "position:absolute;clip:rect(0,1,1,0);overflow:hidden";
	obj.style.position = "absolute";
	obj.style.overflow = "hidden";
	obj.style.clip = "rect(0px,1px,1px,0px)";
	obj.style.background = _color;
	obj.innerHTML = "<span style=\"line-height:1px;font-size:1px\"> </span>";
	obj.width = 1;
	obj.height = 1;
	obj.style.left = _point.x+"px";
	obj.style.top = _point.y+"px";
	obj.style.zIndex = 50;
	obj.style.margin = "0";
	obj.style.padding = "0";
	obj.style.cursor = "default";
	document.body.appendChild(obj);
}

function drawLabeledPixel(_point, _color, _label) {
	var obj = document.createElement("div");
//	obj.style = "position:absolute;clip:rect(0,1,1,0);overflow:hidden";
	obj.id = _label;
	obj.style.position = "absolute";
	obj.style.overflow = "hidden";
	obj.style.clip = "rect(0px,1px,1px,0px)";
	obj.style.background = _color;
	obj.innerHTML = "<span style=\"line-height:1px;font-size:1px\"> </span>";
	obj.width = 1;
	obj.height = 1;
	obj.style.left = _point.x+"px";
	obj.style.top = _point.y+"px";
	obj.style.zIndex = 50;
	obj.style.margin = "0";
	obj.style.padding = "0";
	obj.style.cursor = "default";
	document.body.appendChild(obj);
}

function drawTargetedPixel(_point, _color, _target, _perv) {
	var obj = document.createElement("div");
	obj.style.position = "absolute";
	obj.style.overflow = "hidden";
	obj.style.clip = "rect(0px,1px,1px,0px)";
	obj.style.background = _color;
	obj.innerHTML = "<span style=\"line-height:1px;font-size:1px\"> </span>";
	obj.width = 1;
	obj.height = 1;
	obj.style.left = _point.x+"px";
	obj.style.top = _point.y+"px";
	obj.style.zIndex = _perv;
	obj.style.margin = "0";
	obj.style.padding = "0";
	obj.style.cursor = "default";
	_target.appendChild(obj);
}

然後來畫畫看:

<pre class="c" name="code">


<script src="graphic2.js"></script>

<body style="background:#AABBCC">


<script>
drawPixel({x:100, y:100}, "#000000");
drawPixels(
	getLine([{x:50,y:50},{x:120,y:200}]),
	"#336699"
);
drawPixels(
	getPolygon(
		[
			{x:120,y:100},
			{x:170,y:100},
			{x:190,y:160},
			{x:100,y:160}
		]
	),
	"#225588"
);
</script>

但是這裡面沒有實現畫圓的方法(在其他地方有做過就是了),也沒有實現填色,大概不符合你的需求,而且速度遠不如html5 canvas,只是當作一個另類的作法。

如果你需要互動畫圖,不是用flash或silverlight,大概就是要用html5 canvas了,問題在於瀏覽器的支援程度,要IE9才能跑。用SVG跟CSS3也可以做出來,但問題也都在瀏覽器支援。

用伺服器端程式產生的圖形,互動效果大概很難達到,不過要看你詳細的需求。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2011-05-16 09:57:52 檢舉

補充一下,線條加粗,其實就是點變「大」,例如把我用的長寬都是1 pixel的點改成3 pixels。不過要變粗,最好要對線條做anti-alias這個要用div來做有點麻煩XD

fillano iT邦超人 1 級 ‧ 2011-05-16 10:02:30 檢舉

剛剛那個畫出來會長這樣:

shunyuan iT邦研究生 1 級 ‧ 2011-05-16 10:17:10 檢舉

大師。

鐵殼心 iT邦高手 1 級 ‧ 2011-05-16 10:38:08 檢舉

fillano提到:
anti-alias

這位是anti-java的兄弟嗎?疑惑

fillano iT邦超人 1 級 ‧ 2011-05-16 17:34:31 檢舉

是外星人的兄弟XD

fillano iT邦超人 1 級 ‧ 2011-05-16 18:04:28 檢舉

快下班了,補個畫圓的:

<pre class="c" name="code">
function getCircle (x,y,r) {
	var points = [];
	for (var i = 0; i> (-Math.round(r/Math.sqrt(2))-1); i--) {
		j = Math.sqrt(Math.pow(r,2) - Math.pow(i,2));
		if (Math.ceil(j)-j > j-Math.floor(j)) {
			j = Math.floor(j);
		} else {
			j = Math.ceil(j);
		}
		points.push({"x":i+x,"y":j+y});
		points.push({"x":i+x,"y":y-j});
		points.push({"x":x-i,"y":j+y});
		points.push({"x":x-i,"y":y-j});
		points.push({"x":j+x,"y":i+y});
		points.push({"x":j+x,"y":y-i});
		points.push({"x":x-j,"y":i+y});
		points.push({"x":x-j,"y":y-i});
	}
	return points;
}

然後在上例html裡面的javascript加上:

<pre class="c" name="code">
drawPixels(
	getCircle(200, 200, 50),
	"#0000FF"
);

就會看到:

fillano iT邦超人 1 級 ‧ 2011-05-16 18:16:25 檢舉

該走了...如果要加粗線條,可以改drawPixel:

<pre class="c" name="code">
function drawPixel(_point, _color) {
	var obj = document.createElement("div");
//	obj.style = "position:absolute;clip:rect(0,1,1,0);overflow:hidden";
	obj.style.position = "absolute";
	obj.style.overflow = "hidden";
	obj.style.clip = "rect(0px,3px,3px,0px)";
	obj.style.background = _color;
	obj.innerHTML = "<span style=\"line-height:3px;font-size:3px\"> </span>";
	obj.width = 3;
	obj.height = 3;
	obj.style.left = (_point.x-1)+"px";
	obj.style.top = (_point.y-1)+"px";
	obj.style.zIndex = 50;
	obj.style.margin = "0";
	obj.style.padding = "0";
	obj.style.cursor = "default";
	document.body.appendChild(obj);
}

這樣線條就會變成3 pixels。看起來:

fillano iT邦超人 1 級 ‧ 2011-05-17 00:43:40 檢舉

睡前來畫個橢圓:

程式貼不下...就不貼了。

fillano iT邦超人 1 級 ‧ 2011-05-17 00:52:27 檢舉

把程式放到gist了:
https://gist.github.com/974816
畫橢圓也很簡單:

<pre class="c" name="code">
drawPixels(
	getEclipse(300, 300, 100, 50),
	"#000000"
);
fillano iT邦超人 1 級 ‧ 2011-05-17 22:39:16 檢舉

另外需要補充幾點:

  1. 這些方法是自己從一些基本公式推導出來的,並不是最佳化的方法。
  2. 想要知道怎樣用更好的方法,可以google一下bresenham這個關鍵字,再加上想要做的形狀例如圓(circle)、橢圓(eclipse)
  3. Shape填色用這個方式來做的話,需要產生的div實在太多,執行效果應該不是很好,所以我也沒啥動力來實現(茶)
  4. 如果用bresenham法來實作,可以利用Xiaolin Wu's line algorithm方法來去掉鋸齒,這是bresenham的進階方法
  5. gist上面貼的程式裡面,還有自己想出來如何快速判斷convex polygon intersection的方法,同樣在網路上應該也可以找到更好的方法

不過,這些程式有些部份很舊了,所以前後風格不太一致哈哈

fillano iT邦超人 1 級 ‧ 2011-05-18 09:42:33 檢舉

在wikipedia看了:變換矩陣的資料,做了簡單的旋轉功能:

不過這樣會使得橢圓的線段不連續XD...其實把畫好的橢圓來旋轉一定會這樣,應該要做出可做出可旋轉任意角度橢圓的方法...哈哈

wordsmith iT邦高手 1 級 ‧ 2011-05-18 09:47:49 檢舉

真神人啊,請受小弟一拜~

簽名簽名簽名

12
ccutmis
iT邦高手 9 級 ‧ 2011-05-16 12:29:22

我也來獻醜了~ 其實用HTML+CSS也是辦得到,不過比較麻煩...下列的網頁執行結果是會畫

<pre class="c" name="code">
<html xmlns="http://www.w3.org/1999/xhtml">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TEST</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
<script type="text/javascript">
var initX=50,initY=50;

var arr01=new Array(10);
arr01[0]=new Array(0,0,1,1,1,1,1,1,0,0);
arr01[1]=new Array(0,1,1,1,1,1,1,1,1,0);
arr01[2]=new Array(1,1,1,0,0,0,0,1,1,1);
arr01[3]=new Array(1,1,0,1,1,1,1,0,1,1);
arr01[4]=new Array(1,1,0,1,1,1,1,0,1,1);
arr01[5]=new Array(1,1,0,1,1,1,1,0,1,1);
arr01[6]=new Array(1,1,0,1,1,1,1,0,1,1);
arr01[7]=new Array(1,1,1,0,0,0,0,1,1,1);
arr01[8]=new Array(0,1,1,1,1,1,1,1,1,0);
arr01[9]=new Array(0,0,1,1,1,1,1,1,0,0);

$(document).ready(function() {
	drawMaze();
});

function drawMaze(){
	var yLen=arr01.length;
	var xLen=arr01[0].length;
	for(var i=0;i<yLen;i++){
		for(var j=0;j<xLen;j++){
			if(arr01[i][j]==0){
				$("body").append("<span class='whiteBlock' style='top:"+(initY+(i*2))+"px;left:"+(initX+(j*2))+"px;'> </span>");
			}else{
				$("body").append("<span class='blackBlock' style='top:"+(initY+(i*2))+"px;left:"+(initX+(j*2))+"px;'> </span>");
			}
		}
	}
}
</script>

<style text="text/css">
.whiteBlock,.blackBlock{display:block;width:2px;height:2px;background:#fff;font-size:2px;line-height:2px;position:absolute;top:100px;left:100px;}
.blackBlock{background:#333;top:100px;left:150px;}
</style>

wordsmith iT邦高手 1 級 ‧ 2011-05-18 09:48:42 檢舉

了不起~
灑花灑花

我要發表回答

立即登入回答