Linien zeichnen

Hallo,
Ich habe ein Script geschrieben, indem man mittels zweier Klicks eine Linie zwischen den beiden angeklickten Stellen zeichnen kann.
Das Ganze funktioniert auch schon ganz gut nur liegen die Endpunkte nicht genau auf den angeklickten Stellen. Außerdem denke ich, dass das Script durchaus noch zu verbessern ist. Habt ihr da ein paar Vorschläge?

Code:
<script type="text/javascript">
clicks = 0;
var a, b = new Array();
document.onclick = function(e) {
	clicks++;
	
	if (clicks == 1) {
		a = new Array(e.pageX, e.pageY);
	} else if (clicks == 2) {
		b = new Array(e.pageX, e.pageY);
		
		line(a, b);
		
		clicks = 0;
	}
}

function line(point1, point2) {
	if (point1[0] == point2[0] && point1[1] == point2[1]) { alert("Ungültige Koordinaten"); return; }
	
	bot = point2;
	top = point1;
	
	//höchsten bzw. am weitesten links liegenden punkt als top bestimmen
	if (point1[1] > point2[1]) {
		top = point2;
		bot = point1;
	} else if (point1[1] == point2[1]) {
		if (point1[0] < point2[0]) {
			top = point2;
			bot = point1;
		}
	}
	
	//richtung des bot punktes im verhältniss zu top
	direction = "R";
	if (top[0] > bot[0]) {
		direction = "L";
	} else if (top[0] == bot[0]) {
		direction = "V";
	}
	
	// zeichenbereich ermitteln
	parent = document.createElement("div");
	
	drawArea = new Array();
	drawArea[1] = bot[1] - top[1];
	if (direction == "L") {
		drawArea[0] = top[0] - bot[0];
		
		parent.style.marginLeft = bot[0];
	} else if (direction == "R") {
		drawArea[0] = bot[0] - top[0];
		
		parent.style.marginLeft = top[0];
	} else {
		drawArea[0] = 1;
	}

	parent.style.marginTop = top[1];
	parent.style.width = drawArea[0];
	parent.style.height = drawArea[1];
	parent.style.position = "absolute";
	document.getElementById("table").appendChild(parent);
	
	//pixelachse ermittlen
	if (drawArea[1] >= drawArea[0]) {
		pxPerLayer = drawArea[1] / drawArea[0];
		
		top = 0;
		if (direction == "R") {
			for (i = 0; i <= drawArea[0]; i++) {
				el = document.createElement("div");
				el.style.marginLeft = i;
				el.style.marginTop = top;
				el.style.backgroundColor = "red";
				el.style.width = "1px";
				el.style.height = pxPerLayer + "px";
				el.style.position = "absolute";
				parent.appendChild(el);
				
				top += pxPerLayer;
			}
		} else if (direction = "L") {
			for (i = drawArea[0]; i >= 0; i--) {
				el = document.createElement("div");
				el.style.marginLeft = i;
				el.style.marginTop = top;
				el.style.backgroundColor = "red";
				el.style.width = "1px";
				el.style.height = pxPerLayer + "px";
				el.style.position = "absolute";
				parent.appendChild(el);
				
				top += pxPerLayer;
			}
		}
	} else if (drawArea[1] < drawArea[0]) {
		pxPerLayer = drawArea[0] / drawArea[1];
		
		left = 0;
		if (direction == "R") {
			for (i = 0; i <= drawArea[1]; i++) {
				el = document.createElement("div");
				el.style.marginLeft = left;
				el.style.marginTop = i;
				el.style.backgroundColor = "red";
				el.style.width = pxPerLayer + "px";
				el.style.height = "1px";
				el.style.position = "absolute";
				parent.appendChild(el);
				
				left += pxPerLayer;
			}
		} else if (direction = "L") {
			for (i = drawArea[1]; i >= 0; i--) {
				el = document.createElement("div");
				el.style.marginLeft = left;
				el.style.marginTop = i;
				el.style.backgroundColor = "red";
				el.style.width = pxPerLayer + "px";
				el.style.height = "1px";
				el.style.position = "absolute";
				parent.appendChild(el);
				
				left += pxPerLayer;
			}
		}
	}
}
</script>
<div id="table"></div>
Ach ja: Bitte keine fertigen Scripte aus externen Quellen, ich würde gerne wissen wo mein Denkfehler liegt. ;)

MfG Lük
 
Grundsätzlich: Warum operierst du mit marginLeft und marginTop, und nicht direkt mit left und top? Außerdem solltest du konsequent "px" an die Maßangaben anhängen, sonst funktioniert's nicht überall.

Wenn das bedacht ist, und auch die Default-Margins und -Paddings des HTML-Bodys, die die Browser definieren, ausgeschaltet sind, hauen die Linien bei mir schon meistens hin. Problematisch wird's nur dann, wenn man in einer Koordinate nur wenig Abweichung hat, beispielsweise fast auf gleicher Höhe 2 Punkte in größerem Abstand definiert... dann wird die Linie nämlich länger als sie soll (genau 1 "Element" länger). Ich tippe mal, das kommt durch Rundungsprobleme. Linien, die genau senkrecht oder waagerecht verlaufen, kann ich auch nicht malen, dieser Fall wird bei dir noch nicht berücksichtigt.
 
Grundsätzlich: Warum operierst du mit marginLeft und marginTop, und nicht direkt mit left und top?
Keine Ahnung ;) ist geändert.

Außerdem solltest du konsequent "px" an die Maßangaben anhängen, sonst funktioniert's nicht überall.
Auch getan.

Wenn das bedacht ist, und auch die Default-Margins und -Paddings des HTML-Bodys, die die Browser definieren, ausgeschaltet sind, hauen die Linien bei mir schon meistens hin.
Das lässt sich doch mit <body marginheight="0" marginwidth="0"> abschalten, oder?

Problematisch wird's nur dann, wenn man in einer Koordinate nur wenig Abweichung hat, beispielsweise fast auf gleicher Höhe 2 Punkte in größerem Abstand definiert... dann wird die Linie nämlich länger als sie soll (genau 1 "Element" länger). Ich tippe mal, das kommt durch Rundungsprobleme.
Ursache war nicht die Rundung, sondern ein = in der for-Schleife, hier reicht ein einfaches < bzw. >.

Linien, die genau senkrecht oder waagerecht verlaufen, kann ich auch nicht malen, dieser Fall wird bei dir noch nicht berücksichtigt.
Ist jetzt möglich.

Vielen Dank schonmal! Mittlerweile läuft das Script ganz ordentlich. Hier mal die aktuelle Version:

Code:
<script type="text/javascript">
clicks = 0;
var a, b = new Array();
document.onclick = function(e) {
	clicks++;
	
	if (clicks == 1) {
		a = new Array(e.pageX, e.pageY);
	} else if (clicks == 2) {
		b = new Array(e.pageX, e.pageY);
		
		line(a, b);
		
		clicks = 0;
	}
}

function line(point1, point2) {
	if (point1[0] == point2[0] && point1[1] == point2[1]) { alert("Ungültige Koordinaten"); return; }
	
	bot = point2;
	top = point1;
	
	//höchsten bzw. am weitesten links liegenden punkt als top bestimmen
	if (point1[1] > point2[1]) {
		top = point2;
		bot = point1;
	} else if (point1[1] == point2[1]) {
		if (point1[0] < point2[0]) {
			top = point2;
			bot = point1;
		}
	}
	
	//richtung des bot punktes im verhältniss zu top
	direction = "R";
	if (top[0] >= bot[0]) {
		direction = "L";
	}
	
	// zeichenbereich ermitteln
	parent = document.createElement("div");
	
	drawArea = new Array();
	drawArea[1] = (bot[1] - top[1]) + 1;
	if (direction == "L") {
		drawArea[0] = (top[0] - bot[0]) + 1;
		
		parent.style.left = bot[0] + "px";
	} else if (direction == "R") {
		drawArea[0] = (bot[0] - top[0]) + 1;
		
		parent.style.left = top[0] + "px";
	}

	parent.style.top = top[1] + "px";
	parent.style.width = drawArea[0] + "px";
	parent.style.height = drawArea[1] + "px";
	parent.style.position = "absolute";
	document.getElementById("table").appendChild(parent);
	
	//pixelachse ermittlen
	if (drawArea[1] >= drawArea[0]) {
		pxPerLayer = drawArea[1] / drawArea[0];
		
		top = 0;
		if (direction == "R") {
			for (i = 0; i < drawArea[0]; i++) {
				div(i, top, pxPerLayer, 1, "red");
				top += pxPerLayer;
			}
		} else if (direction = "L") {
			for (i = drawArea[0]; i > 0; i--) {
				div(i, top, pxPerLayer, 1, "red");
				top += pxPerLayer;
			}
		}
	} else if (drawArea[1] < drawArea[0]) {
		pxPerLayer = drawArea[0] / drawArea[1];
		
		left = 0;
		if (direction == "R") {
			for (i = 0; i < drawArea[1]; i++) {
				div(left, i, 1, pxPerLayer, "red");
				left += pxPerLayer;
			}
		} else if (direction = "L") {
			for (i = drawArea[1]; i > 0; i--) {
				div(left, i, 1, pxPerLayer, "red");
				left += pxPerLayer;
			}
		}
	}
	
	function div(left, top, height, width, color) {
		el = document.createElement("div");
		el.style.left = left + "px";
		el.style.top = top + "px";
		el.style.backgroundColor = color;
		el.style.width = width + "px";
		el.style.height = height + "px";
		el.style.position = "absolute";
		parent.appendChild(el);
	}
}
</script>
<body marginheight="0" marginwidth="0">
<div id="table"></div>
</body>

Jetzt kommt mir aber eine weitere Frage auf: Ist es Möglich die Länge einer diagonalen Linie in px-Einheit zu messen?
 
Die Margins und Paddings würde ich ja lieber mittels CSS abschalten, marginheight und marginwidth sind nicht ganz state-of-the-art ;)

Original von :::Lük:::
Jetzt kommt mir aber eine weitere Frage auf: Ist es Möglich die Länge einer diagonalen Linie in px-Einheit zu messen?
Das konnte schon Meister Pythagoras vor zweieinhalbtausend Jahren ;)
 
Ähmmm... "State of the Art" im Zusammenhang mit Liniendarstellung, indem man Pixel als Divs erzeugt und mit deren Aneinanderreihung Linien darstellt? Na ja...

Ansonsten (die Prämisse mal geschluckt, daß es ein sinnvolles Einsatzgebiet gibt): Das Programm müßte dringend entwanzt werden!

- Etwa 20...30 Stellen, wo Variablen ohne Deklaration verwendet werden.
- Mehrere Stellen, wo ein Vergleich stattfinden soll, aber eine Zuweisung ausgeführt wird.
- Fehlerhafte CSS-Wertzuweisungen, die vom Browser einfach ignoriert werden.

Für das Zeichnen: Besser geeignet wäre "SVG": Das versteht heutzutage jeder Browser.
Es wird dabei etwas weniger als hunderte Kilo- oder gar Megabyte RAM pro einfacher Linie verbraucht und so etwa um den Faktor zigtausend schneller gezeichnet.
Wobei ich aber selbst noch auf der Suche nach einem anständigen Tutorial für direktes Steuern einer SVG aus dem Javascript des umgebenden Dokuments heraus bin: Für Javascript INNERHALB eines SVGs gibt es ausreichend Material, aber für dessen Erzeugung von außen habe ich noch nichts gefunden.

Ob Lük mal einen Blick auf SVG werfen kann?
 
Original von LX
Das konnte schon Meister Pythagoras vor zweieinhalbtausend Jahren ;)

thx :)

Original von Harry Boeck
die Prämisse mal geschluckt, daß es ein sinnvolles Einsatzgebiet gibt

Habe ich das behauptet?

- Etwa 20...30 Stellen, wo Variablen ohne Deklaration verwendet werden.

Naja...natürlich gehört dies zu einem gutem Stil aber ändern tut sich dadurch doch nichst (oder?)

Mehrere Stellen, wo ein Vergleich stattfinden soll, aber eine Zuweisung ausgeführt wird.

Danke

Fehlerhafte CSS-Wertzuweisungen, die vom Browser einfach ignoriert werden.

Welchen Browser benutzt du denn? Bei mir funtioniert es.

Für das Zeichnen: Besser geeignet wäre "SVG": Das versteht heutzutage jeder Browser.

Naja... Der IE wird zum Beispiel nicht von Haus aus damit ausgestattet.

Ob Lük mal einen Blick auf SVG werfen kann?
Klar kann er das ;) allerdings war mir nicht wichtig das Programm möglichst perfomant zu machen (sonst hätte ich das ganze sowiso mit einer GUI in C++ gemacht).
Javascript finde ich persönlich sehr bequem und desshalb ich das Problem damit gelöst.
 
Zurück
Oben