Ritverktyg med enbart HTML och Javascript! :-)

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av JimmyAndersson »

Det var så länge sedan jag gjorde något med javascript, så jag fick lust att göra något.
Då föddes en knasig idé: Varför inte använda vanliga html-tabeller för att göra en mätare med "analog" visare?
Fullständigt normalt, eller hur? :D



Jag tar en liten genomgång först, med de olika kodsegmenten.
Sist kommer en fullständig kod. Bara att kopiera och köra.





Först behöver vi något som definierar hur en pixel ska se ut när den är tänd, respektive släckt:
("Släckt" bör förstås motsvaras av bakgrundsfärgen.)
Det görs med vanlig css, här direkt i html-filen:

Kod: Markera allt

<style>
	.on {background-color: #FF0000;}
	.off {background-color: #EEEEEE;}
</style>



Sedan själva Javascripten. Allt här nedan är i Javascript.




Vi måste först bestämma lite saker. T.ex hur stor rityta, storlek på pixeln, mm.
Det mesta är ganska tydligt, men inbjuder även till trial-and-error, så prova gärna andra värden.

Kod: Markera allt

//Settings
var resolution_x = 50;
var resolution_y = 20;
var pixel_size = 2;
var meter_length = 90;
var delay = 30;
var runstop_mode = 1; // 1 = run from start.
var move_run = 0; //Move-buttons from start?
//--------



Sedan ska själva ytan skapas. Dvs tabellen. Det gör den här funktionen:

Kod: Markera allt

function create() //Create the tablespace.
	{
	var pos = 0;
	
	var table_start = "<table id=graph border=0 cellspacing=0 cellpadding=0>";
	var table_end = "</table>";
	var tr_start = "<tr bgcolor=#EEEEEE>";
	var tr_end = "</tr>";
	var td_start = "<td width=" + pixel_size + " height=" + pixel_size + " ";
	var td_end = "</td>";

	document.write(table_start);
	for (var r = resolution_y; r >= 1; r--)
		{
		document.write(tr_start);
		for (var c = 1; c <= resolution_x; c++)
			{
			pos = 'a' + (((r - 1) * resolution_x) + c);
			document.write(td_start + "id=" + pos + ">" + td_end);
			}
		}
	document.write(table_end);
	}


Den här funktionen ritar en pixel på vald plats i tabellen:

Kod: Markera allt

function draw(x,y,pen) //Put or remove a pixel.
	{
	var set_pos = 'a' + (((y - 1) * resolution_x) + x);
	var z_element = document.getElementById(set_pos);
	z_element.className = pen;
	}


Mer behövs egentligen inte. :)
Allt ovan är alltså själva rit-grejen. Resten är funktioner som använder det.

----


Vad sägs om en studsande boll?

Kod: Markera allt

function tennis() //Bounce.
	{
	move_run = 1;
    var cx = 1;
    var cy = 1;
	var direction_x = 1;
	var direction_y = 1;
	var cx_old = 0;
	var cy_old = 0;
	var pi = 3.14159;

    (
	function()
		{
		if (cx_old > 0) {draw(cx_old,cy_old,"off")}
		draw(cx,cy,"on")

		cx_old = cx;
		cy_old = cy;
		cx = cx + direction_x;
		cy = cy + direction_y;

		if (cx >= resolution_x) {direction_x = -direction_x;}
		if (cx <= 1) {direction_x = -direction_x;}
		if (cy >= resolution_y) {direction_y = -direction_y;}
		if (cy <= 1) {direction_y = -direction_y;}

		if (runstop_mode == 1) {setTimeout(arguments.callee, delay);}
		}
	)
	();
	}
Kör man funktionen flera gånger efter varandra så får man många studsande bollar. :)




Nästa funktion är det som var min ursprungliga idé: En mätare med "analog" visare! :mrgreen:

Kod: Markera allt

function meter(value_x)
	{
	var pi = 3.14;
	var end_x = Math.round(resolution_x / 2);
	var end_y = 0;

	var cx = Math.round(value_x / 2);
	var cy = Math.round(Math.sin((cx/resolution_x)*pi)*(0.3*resolution_x));
	if (cy >= resolution_y) {cy = resolution_y;}

	var cx_step = (cx - end_x) / meter_length;
	var cy_step = (cy - end_y) / meter_length;

	var meter_x = cx;
	var meter_y = cy;

	for (var temp_y = meter_y; temp_y >= 0; temp_y-=cy_step)
		{
		var meter_x = meter_x - cx_step;

		draw(Math.round(meter_x), Math.round(temp_y), "on");
		}
	}

Anropa med ett tal mellan 0-100. T.ex meter(50) för att få en nål som står rakt upp.
Tyvärr lider den sistnämnda funktionen av ett litet problem:
Man kan bara anropa den 1st gång. För ett nytt värde så måste man ladda om sidan.
Så det återstår att fixa.






Här är hela paketet, för fortsatta laborationer:

Kod: Markera allt

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

<style>
	.on {background-color: #FF0000;}
	.off {background-color: #EEEEEE;}
</style>

<script type="text/javascript">

//Settings
var resolution_x = 50;
var resolution_y = 20;
var pixel_size = 2;
var meter_length = 90;
var delay = 30;
var runstop_mode = 1; // 1 = run from start.
var move_run = 0; //Move-buttons from start?
//--------


function create() //Create the tablespace.
	{
	var pos = 0;
	
	var table_start = "<table id=graph border=0 cellspacing=0 cellpadding=0>";
	var table_end = "</table>";
	var tr_start = "<tr bgcolor=#EEEEEE>";
	var tr_end = "</tr>";
	var td_start = "<td width=" + pixel_size + " height=" + pixel_size + " ";
	var td_end = "</td>";

	document.write(table_start);
	for (var r = resolution_y; r >= 1; r--)
		{
		document.write(tr_start);
		for (var c = 1; c <= resolution_x; c++)
			{
			pos = 'a' + (((r - 1) * resolution_x) + c);
			document.write(td_start + "id=" + pos + ">" + td_end);
			}
		}
	document.write(table_end);
	}
	

function draw(x,y,pen) //Put or remove a pixel.
	{
	var set_pos = 'a' + (((y - 1) * resolution_x) + x);
	var z_element = document.getElementById(set_pos);
	z_element.className = pen;
	}
	


function tennis() //Bounce.
	{
	move_run = 1;
    var cx = 1;
    var cy = 1;
	var direction_x = 1;
	var direction_y = 1;
	var cx_old = 0;
	var cy_old = 0;
	var pi = 3.14159;

    (
	function()
		{
		if (cx_old > 0) {draw(cx_old,cy_old,"off")}
		draw(cx,cy,"on")

		cx_old = cx;
		cy_old = cy;
		cx = cx + direction_x;
		cy = cy + direction_y;

		if (cx >= resolution_x) {direction_x = -direction_x;}
		if (cx <= 1) {direction_x = -direction_x;}
		if (cy >= resolution_y) {direction_y = -direction_y;}
		if (cy <= 1) {direction_y = -direction_y;}

		if (runstop_mode == 1) {setTimeout(arguments.callee, delay);}
		}
	)
	();
	}



function scale()
	{
    var cx = 1;
    var cy = 1;
	var pi = 3.14159;

	for (var cx = 1; cx <= resolution_x; cx++)
		{
		cy = Math.round(Math.sin((cx/resolution_x)*pi)*(0.3*resolution_x));
		if (cy >= resolution_y) {cy = resolution_y;}
		draw(cx,cy,"on")
		}
	}



function meter(value_x)
	{
	var pi = 3.14;
	var end_x = Math.round(resolution_x / 2);
	var end_y = 0;

	var cx = Math.round(value_x / 2);
	var cy = Math.round(Math.sin((cx/resolution_x)*pi)*(0.3*resolution_x));
	if (cy >= resolution_y) {cy = resolution_y;}

	var cx_step = (cx - end_x) / meter_length;
	var cy_step = (cy - end_y) / meter_length;

	var meter_x = cx;
	var meter_y = cy;

	for (var temp_y = meter_y; temp_y >= 0; temp_y-=cy_step)
		{
		var meter_x = meter_x - cx_step;

		draw(Math.round(meter_x), Math.round(temp_y), "on");
		}
	}




function runstop(rs)
	{
	runstop_mode = rs;
	}

</script>
</head>
<body>


<script type="text/javascript">
create()
tennis()

</script>

<script type="text/javascript">
if (move_run == 1)
	{
	document.write("<br><br><br><br>");
	document.write('<input type="button" value="Run" onclick="runstop(1);move()">');
	document.write('<input type="button" value="Stop" onclick="runstop(0)">');
	}
</script>

</body>
</html>
Funktionen scale() ritar en halv cirkel (ungefär) och var grunden till funktionen meter().
Den sista javascript-grejen är för att visa knapparna "Run" och "Stop", som används till tennis().





Ni får gärna använda vad ni vill och gärna modifiera efter önskemål.
Enda förbehållet är: Om ni kopierar något rakt av så får ni inte påstå att det är ni som gjort koden. :)


Glad påsk!
Användarvisningsbild
chille
Inlägg: 2469
Blev medlem: 25 juni 2003, 20:54:41
Ort: Stockholm
Kontakt:

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av chille »

Du har inte funderat på att rita i en HTML5 canvas istället? :mrgreen:
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av sodjan »

Eller en färdig graf-modul byggt på Canvas: http://www.rgraph.net/.
Jag har testat lite och det är rellativt enkelt att producera vanlig "affärsgrafik" i alla fall.
Ett enkelt exempel: http://jescab2.dyndns.org/html_test/basic.html
Användarvisningsbild
JimmyAndersson
Inlägg: 26308
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av JimmyAndersson »

Va? Finns det färdiga grejer för sånt här? :shock:
Och jag som har jobbat så mycket med detta....


Jag skojar naturligtvis. :)

Efter att jag startade tråden så var jag nyfiken på vad responsen skulle bli.
Att det var en annorlunda och (i de flesta fall) onödig lösning visste jag
och förmodligen skulle jag få reda på det också.
Inget fel i det, så länge det är konstruktivt.

Men förutom det. För det finns ju trots allt dem som gillar annorlunda idéer.

Men det blev helt tyst. Ända tills era inlägg.




Chille: :D
HTML 5 Canvas har jag kikat lite på tidigare. Det är ett enkelt och snyggt sätt att påverka text/grafik.
Grunden påminner lite om de extrafunktioner som Internet Explorer stödde i mitten av 90-talet.

Sodjan:
RGraph hade jag inte sett tidigare. Det var kul att se exemplet med tankmätaren
och jag ska nog titta närmare på det. Det verkar ganska kraftfullt.



Men.. min lösning är roligare. :)
Inte roligare som i "det är kul att uppfinna hjulet igen", utan som i:
"Jag fick en idé, men visste inte hur jag skulle gå till väga.
Så jag lärde mig efter hand och nu kan jag både mer matte och mer Javascript än innan."

Dessutom har jag fått bekräftat att jag är så pass knasig att jag kan använda html-tabeller för sånt här.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av sodjan »

Det är egentligen ingen skillnad på Chilles och mitt inlägg.
RGraph är bara en implementering byggt på Canvas från HTML5.
Horatius
Inlägg: 216
Blev medlem: 5 augusti 2008, 01:00:01
Ort: Kisa

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av Horatius »

Stiligt Jimmy! Senast jag gjorde något liknande valde jag att låta en server generera en PNG från en service skriven i C#. HTTP-klienterna
fick sedan nöja sig med att läsa in samma bild under dess livslängd. På den tiden fanns inte HTML5 (åtminstone var det ingenting jag kände till och kunde förutsätta fanns på alla klienter) men din metod hade nog fungerat.

Mig veterligen används programmet fortfarande av en global industrikoncern för att visa produktionsreslutat på storbildskärmar i fabnrikerna världen över. Det är lite synd
att vi kodapor inte får betalt för varje gång koden körs.
Pajn
Inlägg: 1160
Blev medlem: 6 juni 2008, 19:14:29
Ort: Nyköping
Kontakt:

Re: Ritverktyg med enbart HTML och Javascript! :-)

Inlägg av Pajn »

Skulle jag göra en mätare med analoga visare skulle jag nog välja en statisk bild som
jag sedan roterade visaren med en CSS transform, eller kanske ännu hellre SVG
och en SVG transform.

Jag håller faktiskt på med ett webbaserat ritverktyg just nu i Dart, Angular och SVG.
Ganska kul faktiskt :)
Skriv svar