<html><head><meta name="viewport" content="width=device-width, initial-scale=1"><title>Un canvas pour comprendre les fonctions trigonométriques</title></head><body><h1>Un canvas pour comprendre les fonctions trigonométriques</h1><p>Un canvas en mode responsive design</p><div id="trigo" class="dessin"><canvas id="myCanvas"></canvas></div><div> <div class="btn" onclick="startAnimation()">Start animation</div> <div class="btn" onclick="stopAnimation()">Stop animation</div></div><div id="PIs"> </div><script type="text/javascript">var myCanvas=document.getElementById("myCanvas");var container=myCanvas.parentElement;const PI=Math.PI;var angle=1*PI/3;var animationID=0;var valeurs=["0", "PI/6", "PI/4", "PI/3", "PI/2", "2*PI/3", "3*PI/4", "PI", "5*PI/4"];/* Création des boutons de valeurs particulières */var PIs=document.getElementById("PIs");for (var i=0; i<valeurs.length; i++) { var btn=document.createElement("div"); btn.className="btn"; btn.innerHTML="angle="+valeurs[i]; btn.setAttribute("onclick", "angle="+eval(valeurs[i])+"; displayTrigo("+eval(valeurs[i])+")"); btn.setAttribute("id","angle"+i); PIs.appendChild(btn);}/* Fonctions déclenchées par les boutons */function startAnimation() { if (animationID==0) {animationTrigo();}}function stopAnimation() { if (animationID>=0) { window.cancelAnimationFrame(animationID); animationID=0; }}/* Détection du changement de taille de la fenêtre */window.addEventListener("resize", function() { displayTrigo(angle);});/* Fonction de callback de requestAnimationFrame */function animationTrigo(timer) { angle+=0.01; if (angle>2*PI) {angle=0;} /* Si un tour complet */ displayTrigo(angle); animationID=window.requestAnimationFrame(animationTrigo);}/* Détection du mouvement de souris sur le canvas */myCanvas.addEventListener("mousemove", function(evt) { if (animationID>0) {return false;} /* On sort si mode animation */ /* On redessine le canvas avec les informations de position de souris */ displayTrigo(angle); TJScanvas.ctx.beginPath() TJScanvas.ctx.fillStyle="#f00"; TJScanvas.ctx.arc(evt.offsetX, evt.offsetY, 8, 0, 2*PI ); TJScanvas.ctx.fill(); /* Conversion des coordonnées de souris en pixels dans le référentiel */ var x=(evt.offsetX-TJScanvas.deltaX)/TJScanvas.echelle; x=x.toFixed(3); var y=(evt.offsetY-TJScanvas.deltaY)/TJScanvas.echelle; y=y.toFixed(3); TJScanvas.ctx.fillText("("+evt.offsetX+"px, "+evt.offsetY+"px) => ("+x+","+y+")", evt.offsetX-90, evt.offsetY-15); TJScanvas.ctx.strokeStyle="#f00"; TJScanvas.drawLine(0,0,x,y); /* Calcul de l'angle avec arctangeante */ if (x>0) { angle=-1*Math.atan(y/x); } else { angle=PI-1*Math.atan(y/x); }});/* TJScanvas est l'objet permettant d'afficher le canvas */var TJScanvas={ width: 0, height: 0, padding: 0, deltaX:0, deltaY:0, echelle:0, ctx:null, clearCanvas: function() { this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); }, drawLine: function(x1, y1, x2, y2) { this.ctx.beginPath(); this.ctx.moveTo(x1*this.echelle+this.deltaX, y1*this.echelle+this.deltaY); this.ctx.lineTo(x2*this.echelle+this.deltaX, y2*this.echelle+this.deltaY); this.ctx.stroke(); }, drawCircle: function(x, y, r, a1=0, a2=2*PI) { this.ctx.beginPath(); this.ctx.arc( x*this.echelle+this.deltaX, y*this.echelle+this.deltaY, r*this.echelle, a1, a2); this.ctx.stroke(); }, fillCircle: function(x, y, r, a1=0, a2=2*PI) { this.ctx.beginPath(); this.ctx.arc( x*this.echelle+this.deltaX, y*this.echelle+this.deltaY, r*this.echelle, a1, a2); this.ctx.fill(); }, text: function(txt, x, y, dX=0, dY=0) { this.ctx.fillText(txt, x*this.echelle+this.deltaX+dX, y*this.echelle+this.deltaY+dY); }};/* Fonction principale d'affichage du cercle trigonométrique */function displayTrigo(angle) { /* Forcer la taille du canvas avec la taille du div container */ TJScanvas.width=container.getBoundingClientRect().width; TJScanvas.height=container.getBoundingClientRect().height; /* Optimisation de la hauteur de canvas */ TJScanvas.height=Math.min(TJScanvas.width,500); container.style.height=TJScanvas.height+"px"; myCanvas.setAttribute("width", TJScanvas.width); myCanvas.setAttribute("height", TJScanvas.height); /* Effacer le canvas avant de le redessiner entièrement */ TJScanvas.ctx=myCanvas.getContext("2d"); TJScanvas.clearCanvas(); /* Affichage de la dimension du canvas en pixels */ TJScanvas.ctx.font="bold 14px arial"; TJScanvas.ctx.fillStyle="rgb(0,140,0)"; TJScanvas.ctx.fillText(TJScanvas.width+"x"+TJScanvas.height, 5, 15); /* Correspondance reférentiel interne et taille du canvas */ /* position (0,0) au centre du */ TJScanvas.padding=25; /* Bordures libres en px */ TJScanvas.deltaX=TJScanvas.width/2; /* translationX du point (0,0) */ TJScanvas.deltaY=TJScanvas.height/2; /* translationY du point (0,0) */ TJScanvas.echelle=(TJScanvas.height-2*TJScanvas.padding)/2 / 1.1; /* tracé du référentiel */ TJScanvas.drawLine(-1.1,0,1.1,0); TJScanvas.drawLine(0,-1.1,0,1.1); TJScanvas.drawCircle(0,0,1); TJScanvas.ctx.fillStyle="rgb(0,0,0)"; TJScanvas.text("1", 1, 0, 5, 20); TJScanvas.text("-1", -1, 0, -20, 20); TJScanvas.text("1", 0, -1, 5, -5); TJScanvas.text("-1", 0, 1, 5, 17); /* Tracé des informations de trigonométrie */ angleTrigo=angle; angle=-1*angle; var x=Math.cos(angle), y=Math.sin(angle); TJScanvas.fillCircle(x, y, 5/TJScanvas.echelle); TJScanvas.ctx.strokeStyle="rgb(0,140,0)"; TJScanvas.ctx.lineWidth=2; TJScanvas.drawCircle(0, 0, 0.2, angle, 0); /* arc de angle */ TJScanvas.drawLine(0,0,x,y); /* Rayon */ TJScanvas.ctx.lineWidth=1; TJScanvas.ctx.setLineDash([3,3]); TJScanvas.drawLine(x,0,x,y); /* axe des Y */ TJScanvas.drawLine(0,y,x,y); /* axe des X */ /* Libelles */ TJScanvas.ctx.fillStyle="rgb(0,140,0)"; var txt="cos(angle)"; var w=TJScanvas.ctx.measureText(txt).width; if (y<0) { TJScanvas.text(txt, x, 0, -1*w/2, 15); } else { TJScanvas.text(txt, x, 0, -1*w/2, -10); } var txt="sin(angle)"; var w=TJScanvas.ctx.measureText(txt).width; if (x<0) { TJScanvas.text(txt, 0, y,5, 4); } else { TJScanvas.text(txt, 0, y, -1*w-5, 4); } var txt="("+Math.cos(angleTrigo).toFixed(3)+","+Math.sin(angleTrigo).toFixed(3)+")"; var w=TJScanvas.ctx.measureText(txt).width; if (x<0) { TJScanvas.text(txt, x, y, -8-w, 4); } else { TJScanvas.text(txt, x, y, 8, 4); } /* Tableau des angles remarquables en fraction de PI */ var txtAngle=""; for (var i=0; i<valeurs.length; i++) { document.getElementById("angle"+i).style.backgroundColor="#fff"; if (angleTrigo.toFixed(3)==eval(valeurs[i]).toFixed(3)) { var txtAngle=" = "+valeurs[i]; document.getElementById("angle"+i).style.backgroundColor="#0f0"; } } TJScanvas.ctx.font="italic 14px arial"; var txt="angle"+txtAngle; var w=TJScanvas.ctx.measureText(txt).width; TJScanvas.text(txt, 0.2*Math.cos(angle/2), 0.2*Math.sin(angle/2), 5, 0);}window.onload=function() { displayTrigo(angle);}</script><style type="text/css"> div.dessin { background: #fff; padding:0px; text-align: center; height:300px; min-width:300px; } canvas#myCanvas { } div.btn { display:inline-block; margin:5px; padding:6px; border:1px solid #000; border-radius: 5px; cursor: pointer; background:#fff; color:#000; } div.btn:hover { color:#fff; background: #000 !important; } </style></body></html>