Dessiner des cercles/disques/lignes en javascript

Soyez le premier à donner votre avis sur cette source.

Vue 24 155 fois - Téléchargée 659 fois

Description

Cette source permet de dessiner des cercles, des disques et des lignes en javascript sans utiliser des outils tels que SVG ou Canvas, cela permet d'être utilisable sous la plupart des navigateurs, mais il n'y a pas vraiment de lissage et c'est un peu lent.

Astuces :

Pour faire un cercle lissé et flou mettez par exemple ceci comme paramètres :
- Rayon : 150
- Epaisseur du cercle : 50
- Opacité du cercle : très basse ( entre 1 et 20 )

Pour faire une ligne lissée :
- Epaisseur de la ligne : plus grande que 3 de préférence
- Opacité de la ligne: faible ( entre 1 et 20 )

D'autres possibilités existent, il suffit de tester.

Et n'hésitez pas à me dire si vous avez des bugs !

:)

Source / Exemple :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
	<head>
		<meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
		<script type="text/javascript">
		<!--
			function drawCircle(a, b, r, w, c, o) {
				if (document.getElementById('full').checked) {
					var h = 1;
				}
				else {
					var h = w;
				}
				var y = 0;
				for (x = 0; x <= Math.round(r / Math.sqrt(2)); x++) {
					y = Math.sqrt(Math.pow(r, 2) - (Math.pow(x, 2)));
					if (!document.getElementById('full').checked) {
						setPx(x + a, y + b, w, h, c, o);
						setPx(a - x, y + b, w, h, c, o);
						setPx(a - x, b - y, w, h, c, o);
						setPx(x + a, b - y, w, h, c, o);
						setPx(y + a, b - x, w, h, c, o);
						setPx(a - y, b - x, w, h, c, o);
						setPx(y + a, x + b, w, h, c, o);
						setPx(a - y, x + b, w, h, c, o);
					}
					else {
						setPx(a - x, y + b, 2 * x, h, c, o);
						setPx(a - x, b - y, 2 * x, h, c, o);
						setPx(a - y, b - x, 2 * y, h, c, o);
						setPx(a - y, x + b, 2 * y, h, c, o);
					}
				}
			}

			function drawLine(x1, y1, x2, y2, w, c, o) {
				var y = x = 0;
				var signX = (x1 - x2) / Math.abs(x1 - x2) * -1;
				var signY = (y1 - y2) / Math.abs(y1 - y2) * -1;
				if (x2 == x1) {
					setPx(Math.min(x1, x2), Math.min(y1, y2), w, Math.abs(y2 - y1), c, o);
				} else if (y1 == y2) {
					setPx(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), w, c, o);
				} else {
					if (Math.abs((y2 - y1) / (x2 - x1)) <= 1) {
						while (x <= Math.abs(x2 - x1)) {
							y = (y2 - y1) / Math.abs(x2 - x1) * x;
							setPx(signX * x + x1, y + y1, w, w, c, o);
							x++;
						}
					} else {
						while (y <= Math.abs(y2 - y1)) {
							x = (x2 - x1) / Math.abs(y2 - y1) * y;
							setPx(x + x1, signY * y + y1, w, w, c, o);
							y++;
						}
					}
				}
			}
			
			function setPx(x, y, w, h, c, o) {
				var px = document.createElement('div');
				px.id = 'px';
				px.style.cssText = 'position:absolute; top:' + y + 'px; left:' + x + 'px; background-color:' + c + '; width:' + w + 'px; height:' + h + 'px; opacity:' + o / 100 + '; filter:alpha(opacity=' + o + ');';
				document.body.appendChild(px);
			}

			function clearPx() {
				while (document.getElementById('px')) {
					document.body.removeChild(document.getElementById('px'));
				}
			}
		// -->
		</script>
		<style type="text/css">
			body {
				font-family:verdana, arial;
				font-size:11px;
				color:#333333;
				cursor:default;
				margin:0px;
			}

				p {
					margin:0px;
					font-weight:normal;
				}
				
				form {
					margin:0px;
				}
				
				#main {
					border:solid 5px #CCCCCC;
					background-color:#F0F0F0;
					text-align:center;
					padding:5px;
					width:500px;
					margin:5px auto 5px auto;
				}
		</style>
		<title>Dessiner en Javascript</title>
	</head>
	<body>
		<div id="main">
			<form method="post" action="javascript:;" style="float:left;">
				<p>
					<span style="font-weight:bold">Cercle</span><br/><br/>
					Abcisse du centre du cercle<br/>
					<input type="text" id="x" value="100"/><br/>
					Ordonnée du centre du cercle<br/>
					<input type="text" id="y" value="100"/><br/>
					Rayon du cercle<br/>
					<input type="text" id="r" value="50"/><br/>
					Epaisseur du cercle<br/>
					<input type="text" id="w" value="1"/><br/>
					Couleur du cercle<br/>
					<input type="text" id="c" value="red"/><br/>
					Opacité du cercle<br/>
					<input type="text" id="o" value="100"/><br/><br/>
					<input type="checkbox" id="full"/><label for="full"> Dessiner plein (disque)</label><br/><br/>
					<input type="submit" value="Afficher"
					onclick="drawCircle(parseInt(document.getElementById('x').value), parseInt(document.getElementById('y').value),
					parseInt(document.getElementById('r').value), parseInt(document.getElementById('w').value),
					document.getElementById('c').value, parseInt(document.getElementById('o').value));"/>
				</p>
			</form>
			<form method="post"  action="javascript:;" style="float:right;">
				<p>
					<span style="font-weight:bold">Ligne</span><br/><br/>
					Abcisse du premier point<br/>
					<input type="text" id="x1" value="80"/><br/>
					Ordonnée du premier point<br/>
					<input type="text" id="y1" value="200"/><br/>
					Abcisse du second point<br/>
					<input type="text" id="x2" value="100"/><br/>
					Ordonnée du second point<br/>
					<input type="text" id="y2" value="100"/><br/>
					Epaisseur de la ligne<br/>
					<input type="text" id="w2" value="1"/><br/>
					Couleur de la ligne<br/>
					<input type="text" id="c2" value="red"/><br/>
					Opacité de la ligne<br/>
					<input type="text" id="o2" value="100"/><br/><br/>
					<input type="submit" value="Afficher"
					onclick="drawLine(parseInt(document.getElementById('x1').value), parseInt(document.getElementById('y1').value),
					parseInt(document.getElementById('x2').value), parseInt(document.getElementById('y2').value),
					parseInt(document.getElementById('w2').value), document.getElementById('c2').value, parseInt(document.getElementById('o2').value));"/>
				</p>
			</form>
			<div style="clear:both;"></div>
			<form method="post"  action="javascript:;" style="border-top:solid 1px #CCCCCC; margin-top:5px; padding-top:5px;">
				<p>
					<input type="submit" value="Effacer" onclick="clearPx();"/>
					<input type="submit" value="Infos" onclick="alert('Attention, cette application Javascript est très lente sous IE (surtout la version 8).\n' +
					'Elle a été testée avec succes sous:\n -Firefox 2\n -Firefox 3.0 RC1\n -IE7\n -IE8 Beta 1\n -Opera 9.26\n -Safari 3.1.1')"/>
				</p>
			</form>
		</div>
	</body>
</html>

Conclusion :


Ce code permet de faire quelques dessins mais est assez ( voire très ) lent sous IE, préférez donc un navigateur comme Opera, Safari ou Firefox pour le tester. (les plus rapides sont Opera et Safari pour ce code).

Codes Sources

A voir également

Ajouter un commentaire Commentaires
lakichemole
Messages postés
253
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
18 mai 2009

10 juil. 2008 à 11:59
oki, donc il sont nul chez oenGL ou c'est juste que y a que la 3D qui les interresse?
cs_Hatchepsut
Messages postés
5
Date d'inscription
dimanche 2 mars 2008
Statut
Membre
Dernière intervention
10 juillet 2008

10 juil. 2008 à 11:44
Je ne pense pas que une multiplication en moins par polygone soit avantageuse. Parce que on ne parle pas de polygones 3D, qui eux peuvent être très nombreux, il s'agit de polygones 2D, en fait la projection des polygones de l'espace dans le plan écran. Et au final, ce nombre de polygones 2D, même si la scène est complexe, n'est pas très grand. Et se préserver d'une multiplication, au regard de toutes celles qui sont nécessaires pour les calculer, pour moi n'a aucun intérêt. Ca reviendrait à faire du 40.003 fps contre 40.0029 ^^
lakichemole
Messages postés
253
Date d'inscription
vendredi 13 juin 2003
Statut
Membre
Dernière intervention
18 mai 2009

10 juil. 2008 à 11:39
Ok merci pour ton explication :) Mais j'imagine que les gars d'openGL on fait ça pour les perf? Car en séssion des million de polygon la multiplication en moins peut faire la différence? Après c'est une question de priorité rendu/performance?
cs_Hatchepsut
Messages postés
5
Date d'inscription
dimanche 2 mars 2008
Statut
Membre
Dernière intervention
10 juillet 2008

10 juil. 2008 à 11:33
Merci MACSOU pour le lien :)

Pour en revenir sur OpenGL, il suffit de dessiner un carré de sommet rouge, vert, bleu, et blanc par exemple. On voit une belle diagonale en plein milieu du carré, inversée si on le regarde de l'autre côté. Ca montre tout simplement la façon de découper les polygones.

Pour dessiner un polygone, on le découpe en triangles, parce que ça on aime bien, et on sait faire. Et OpenGl minimise certes le nombre de triangles, ce que je précise n'a aucun avantage, à part se préserver d'une multiplication par polygone. Au final, si on prend un bon découpage, pour un polygone convexe à n côtés, on devrait avoir n+2 triangles avec la méthode du barycentre. Le nombre de pixels atteints est le même, sauf que le rendu est meilleur. OpenGL n'est pas le seul à faire ça, je pourrais citer VRML par exemple, même si ce n'est pas forcément une référence.
nicomilville
Messages postés
3472
Date d'inscription
lundi 16 juillet 2007
Statut
Membre
Dernière intervention
28 février 2014
37
10 juil. 2008 à 11:28
c'est pas payant je crois !

a++
Afficher les 32 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.