+
+
Trigonometric Functions Visualization
+
+
+ Zoom:
+
+ type="range"
+ id="zoom"
+ min="0.5"
+ max="4"
+ step="0.1"
+ value="1"
+ />
+
+
+
+
+
+
+ const canvas = document.getElementById("chart");
+ const ctx = canvas.getContext("2d");
+ const zoomInput = document.getElementById("zoom");
+
+ let zoom = 1;
+
+ function drawGrid() {
+ const width = canvas.width;
+ const height = canvas.height;
+ const centerX = width / 2;
+ const centerY = height / 2;
+
+ ctx.strokeStyle = "#e0e0e0";
+ ctx.lineWidth = 1;
+
+ // Draw vertical grid lines and x-axis labels
+ for (let x = 0; x <= width; x += 50) {
+ ctx.beginPath();
+ ctx.moveTo(x, 0);
+ ctx.lineTo(x, height);
+ ctx.stroke();
+
+ // Add x-axis labels
+ const xValue = ((x - centerX) * (0.01 / zoom) * Math.PI).toFixed(1);
+ if (x !== centerX) {
+ // Skip 0 as it's handled separately
+ ctx.fillStyle = "#666";
+ ctx.font = "12px sans-serif";
+ ctx.textAlign = "center";
+ ctx.fillText(xValue + "π", x, centerY + 20);
+ }
+ }
+
+ // Draw horizontal grid lines and y-axis labels
+ for (let y = 0; y <= height; y += 50) {
+ ctx.beginPath();
+ ctx.moveTo(0, y);
+ ctx.lineTo(width, y);
+ ctx.stroke();
+
+ // Add y-axis labels
+ const yValue = -((y - centerY) / (100 * zoom)).toFixed(1);
+ if (y !== centerY) {
+ // Skip 0 as it's handled separately
+ ctx.fillStyle = "#666";
+ ctx.font = "12px sans-serif";
+ ctx.textAlign = "right";
+ ctx.fillText(yValue, centerX - 10, y + 4);
+ }
+ }
+
+ // Draw x and y axis
+ ctx.strokeStyle = "#000";
+ ctx.lineWidth = 2;
+
+ // X-axis
+ ctx.beginPath();
+ ctx.moveTo(0, centerY);
+ ctx.lineTo(width, centerY);
+ ctx.stroke();
+
+ // Y-axis
+ ctx.beginPath();
+ ctx.moveTo(centerX, 0);
+ ctx.lineTo(centerX, height);
+ ctx.stroke();
+
+ // Add axis labels
+ ctx.fillStyle = "#000";
+ ctx.font = "bold 14px sans-serif";
+
+ // X-axis label
+ ctx.textAlign = "center";
+ ctx.fillText("x (radians)", width - 40, centerY - 10);
+
+ // Y-axis label
+ ctx.save();
+ ctx.translate(20, height / 2);
+ ctx.rotate(-Math.PI / 2);
+ ctx.fillText("f(x)", 0, 0);
+ ctx.restore();
+
+ // Origin label
+ ctx.textAlign = "right";
+ ctx.fillText("0", centerX - 5, centerY + 15);
+ }
+
+ function plotFunction(fn, color) {
+ ctx.strokeStyle = color;
+ ctx.lineWidth = 2;
+ ctx.beginPath();
+
+ for (let i = 0; i < canvas.width; i++) {
+ const x = (i - canvas.width / 2) * (0.01 / zoom);
+ let y;
+
+ // Handle potential infinity for tan
+ if (fn === Math.tan) {
+ y = Math.abs(fn(x)) > 5 ? NaN : fn(x);
+ } else {
+ y = fn(x);
+ }
+
+ const scaledY = -y * 100 * zoom + canvas.height / 2;
+
+ if (i === 0) {
+ ctx.moveTo(i, scaledY);
+ } else {
+ // Only draw if y is a finite number
+ if (!isNaN(y) && isFinite(y)) {
+ ctx.lineTo(i, scaledY);
+ } else {
+ ctx.moveTo(i, scaledY);
+ }
+ }
+ }
+ ctx.stroke();
+ }
+
+ function draw() {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ drawGrid();
+ plotFunction(Math.sin, "#ff6384");
+ plotFunction(Math.cos, "#36a2eb");
+ plotFunction(Math.tan, "#4bc0c0");
+ }
+
+ zoomInput.addEventListener("input", (e) => {
+ zoom = parseFloat(e.target.value);
+ draw();
+ });
+
+ // Initial draw
+ draw();
+
+
+