Skip to content

Commit

Permalink
on multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
EmeEmu committed Oct 3, 2023
1 parent 3a96420 commit e744890
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 150 deletions.
153 changes: 3 additions & 150 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,12 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Neuro-Behavioral Experiment</title>
<style>
/* Add your CSS styles here */
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: row;
width: 100%;
}
.canvas-container {
flex: 3;
display: flex;
justify-content: center;
align-items: stretch;
}
#canvas {
border: 1px solid black;
max-width: 100%;
max-height: 100%;
}
.right-column {
flex: 1;
display: flex;
flex-direction: column;
}
#description {
flex: 2;
padding: 20px;
}
#controls {
flex: 3;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
</style>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
<div class="container">
<div class="canvas-container">
<canvas id="canvas" width="400" height="400"></canvas>
<canvas id="canvas"></canvas>
</div>
<div class="right-column">
<div id="description">
Expand Down Expand Up @@ -93,112 +52,6 @@ <h1>Welcome to the Neuro-Behavioral Experiment</h1>
</div>
</div>

<script>
// JavaScript code for rendering the procedural image
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const frequencySlider = document.getElementById("frequencySlider");
const speedSlider = document.getElementById("speedSlider");
const contrastSlider = document.getElementById("contrastSlider");
const angleSlider = document.getElementById("angleSlider");
const toggleButton = document.getElementById("toggleButton");

let phase = 0;
let animationRunning = true;

toggleButton.addEventListener("click", () => {
animationRunning = !animationRunning;
if (animationRunning) {
toggleButton.textContent = "Pause Animation";
requestAnimationFrame(updateImage);
} else {
toggleButton.textContent = "Resume Animation";
}
});

// Add event listeners to the sliders to update the image when changed
frequencySlider.addEventListener("input", drawProceduralImage);
speedSlider.addEventListener("input", drawProceduralImage);
contrastSlider.addEventListener("input", drawProceduralImage);
angleSlider.addEventListener("input", drawProceduralImage);

// Add a click event listener to update the angle when the user left-clicks on the canvas
canvas.addEventListener("click", (e) => {
const rect = canvas.getBoundingClientRect();
const centerX = rect.width / 2;
const centerY = rect.height / 2;

const clickX = e.clientX - rect.left;
const clickY = e.clientY - rect.top;

// Calculate the angle in radians based on the click position relative to the canvas center
const deltaX = clickX - centerX;
const deltaY = centerY - clickY; // Invert deltaY to account for canvas coordinate system
const newAngle = Math.atan2(deltaY, deltaX) + Math.PI;

// Convert the angle to degrees and update the angle and angleSlider
const newAngleDegrees = (newAngle * 180) / Math.PI;
angleSlider.value = newAngleDegrees;
drawProceduralImage();
});

function drawProceduralImage() {
const width = canvas.width;
const height = canvas.height;
const frequency = parseFloat(frequencySlider.value);
const contrast = parseFloat(contrastSlider.value) / 100; // Convert contrast to a factor
const angle = parseFloat(angleSlider.value) * (Math.PI / 180); // Convert angle to radians

const imageData = ctx.createImageData(width, height);
const data = imageData.data;

for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
// Calculate the pixel's position in rotated coordinates
const xRotated =
(x - width / 2) * Math.cos(angle) -
(y - height / 2) * Math.sin(angle) +
width / 2;
const yRotated =
(x - width / 2) * Math.sin(angle) +
(y - height / 2) * Math.cos(angle) +
height / 2;

const sineValue = Math.sin(
(xRotated / width) * 2 * Math.PI * frequency +
(phase * Math.PI) / 180,
);
const pixelValue = 128 + 127 * sineValue * contrast; // Apply contrast

const index = (x + y * width) * 4;
data[index] = pixelValue; // Set the pixel value based on the sine wave value and contrast
data[index + 1] = pixelValue; // Green channel
data[index + 2] = pixelValue; // Blue channel
data[index + 3] = 255; // Alpha channel (fully opaque)
}
}

ctx.putImageData(imageData, 0, 0);
}

function updateImage() {
if (animationRunning) {
drawProceduralImage();

// Update the phase based on the speed
phase += parseFloat(speedSlider.value);
if (phase >= 360) {
phase -= 360;
}

// Request the next animation frame
requestAnimationFrame(updateImage);
}
}

// Start the animation loop initially
updateImage();
</script>
<script src="script.js"></script>
</body>
</html>
105 changes: 105 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// JavaScript code for rendering the procedural image
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const frequencySlider = document.getElementById("frequencySlider");
const speedSlider = document.getElementById("speedSlider");
const contrastSlider = document.getElementById("contrastSlider");
const angleSlider = document.getElementById("angleSlider");
const toggleButton = document.getElementById("toggleButton");

let phase = 0;
let animationRunning = true;

toggleButton.addEventListener("click", () => {
animationRunning = !animationRunning;
if (animationRunning) {
toggleButton.textContent = "Pause Animation";
requestAnimationFrame(updateImage);
} else {
toggleButton.textContent = "Resume Animation";
}
});

// Add event listeners to the sliders to update the image when changed
frequencySlider.addEventListener("input", drawProceduralImage);
speedSlider.addEventListener("input", drawProceduralImage);
contrastSlider.addEventListener("input", drawProceduralImage);
angleSlider.addEventListener("input", drawProceduralImage);

// Add a click event listener to update the angle when the user left-clicks on the canvas
canvas.addEventListener("click", (e) => {
const rect = canvas.getBoundingClientRect();
const centerX = rect.width / 2;
const centerY = rect.height / 2;

const clickX = e.clientX - rect.left;
const clickY = e.clientY - rect.top;

// Calculate the angle in radians based on the click position relative to the canvas center
const deltaX = clickX - centerX;
const deltaY = centerY - clickY; // Invert deltaY to account for canvas coordinate system
const newAngle = Math.atan2(deltaY, deltaX) + Math.PI;

// Convert the angle to degrees and update the angle and angleSlider
const newAngleDegrees = (newAngle * 180) / Math.PI;
angleSlider.value = newAngleDegrees;
drawProceduralImage();
});

function drawProceduralImage() {
const width = canvas.width;
const height = canvas.height;
const frequency = parseFloat(frequencySlider.value);
const contrast = parseFloat(contrastSlider.value) / 100; // Convert contrast to a factor
const angle = parseFloat(angleSlider.value) * (Math.PI / 180); // Convert angle to radians

const imageData = ctx.createImageData(width, height);
const data = imageData.data;

for (let x = 0; x < width; x++) {
for (let y = 0; y < height; y++) {
// Calculate the pixel's position in rotated coordinates
const xRotated =
(x - width / 2) * Math.cos(angle) -
(y - height / 2) * Math.sin(angle) +
width / 2;
const yRotated =
(x - width / 2) * Math.sin(angle) +
(y - height / 2) * Math.cos(angle) +
height / 2;

const sineValue = Math.sin(
(xRotated / width) * 2 * Math.PI * frequency + (phase * Math.PI) / 180,
);
const pixelValue = 128 + 127 * sineValue * contrast; // Apply contrast

const index = (x + y * width) * 4;
data[index] = pixelValue; // Set the pixel value based on the sine wave value and contrast
data[index + 1] = pixelValue; // Green channel
data[index + 2] = pixelValue; // Blue channel
data[index + 3] = 255; // Alpha channel (fully opaque)
}
}

ctx.putImageData(imageData, 0, 0);
}

function updateImage() {
if (animationRunning) {
drawProceduralImage();

// Update the phase based on the speed
phase += parseFloat(speedSlider.value);
if (phase >= 360) {
phase -= 360;
}

// Request the next animation frame
requestAnimationFrame(updateImage);
}
}

// Start the animation loop initially
updateImage();
// </script>
40 changes: 40 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
.container {
flex: 1;
display: flex;
flex-direction: row;
width: 100%;
}
.canvas-container {
flex: 3;
display: flex;
justify-content: center;
align-items: stretch;
}
#canvas {
border: 1px solid black;
max-width: 100%;
height: 100%;
}
.right-column {
flex: 1;
display: flex;
flex-direction: column;
}
#description {
flex: 2;
padding: 20px;
}
#controls {
flex: 3;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}

0 comments on commit e744890

Please sign in to comment.