Eye prototype work

This commit is contained in:
Sam 2023-04-29 19:27:11 +12:00
parent 687c44f22e
commit bc01c0e0c9
8 changed files with 553 additions and 46 deletions

View File

@ -12,6 +12,7 @@
<div id="toolbar"> <div id="toolbar">
<br> <br>
<select id="shape-selector"> <select id="shape-selector">
<option value="EyePrototype">EyePrototype</option>
<option value="PolyTwistColourWidth">PolyTwistColourWidth</option> <option value="PolyTwistColourWidth">PolyTwistColourWidth</option>
<option value="FloralPhyllo">FloralPhyllo</option> <option value="FloralPhyllo">FloralPhyllo</option>
<option value="FloralPhyllo_Accident">FloralPhyllo_Accident</option> <option value="FloralPhyllo_Accident">FloralPhyllo_Accident</option>
@ -22,7 +23,6 @@
<option value="Phyllotaxis">Phyllotaxis</option> <option value="Phyllotaxis">Phyllotaxis</option>
<option value="SquareTwist_angle">SquareTwist_angle</option> <option value="SquareTwist_angle">SquareTwist_angle</option>
<option value="rectangle_pattern1">rectangle_pattern1</option> <option value="rectangle_pattern1">rectangle_pattern1</option>
<option value="EyePrototype">EyePrototype</option>
</select> </select>
<div id="custom"></div> <div id="custom"></div>
<br> <br>

View File

@ -67,7 +67,9 @@ async function fetchConfig(className) {
], ],
EyePrototype: [ EyePrototype: [
{ type: "range", min: 1, max: 800, defaultValue: 400, property: "width" }, { type: "range", min: 1, max: 800, defaultValue: 400, property: "width" },
{ type: "range", min: 1, max: 100, defaultValue: 10, property: "squares" }, { type: "range", min: 1, max: 100, defaultValue: 10, property: "blink_speed" },
{ type: "range", min: 0, max: 1, defaultValue: 1, property: "draw_spiral" },
{ type: "range", min: 0, max: 1, defaultValue: 1, property: "draw_pupil" },
{ type: "range", min: 1, max: 10, defaultValue: 1, property: "line_width" }, { type: "range", min: 1, max: 10, defaultValue: 1, property: "line_width" },
{ type: "color", defaultValue: "#2D81FC", property: "colour1" }, { type: "color", defaultValue: "#2D81FC", property: "colour1" },
], ],
@ -273,10 +275,22 @@ function LerpRGB(a, b, t) {
return newColor; return newColor;
} }
function render_clear() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "black"; function drawCenter(width) {
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); console.log("center?")
ctx.strokeStyle = "pink";
ctx.lineWidth = 1
ctx.beginPath();
ctx.moveTo(centerX - width, centerY);
ctx.lineTo(centerX + width, centerY);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(centerX, centerY - width);
ctx.lineTo(centerX, centerY + width);
ctx.closePath();
ctx.stroke();
} }
function render_clear() { function render_clear() {
@ -284,3 +298,4 @@ function render_clear() {
ctx.fillStyle = "black"; ctx.fillStyle = "black";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
} }

View File

@ -73,8 +73,8 @@ function render() {
if (!paused) { if (!paused) {
rotation += deg_per_sec / targetFps; rotation += deg_per_sec / targetFps;
} }
// drawCenter(300)
}); });
render(); render();
}, frameDuration); }, frameDuration);
} }

View File

@ -9,7 +9,7 @@ class BaseShape {
const { element, listener } = addControl(item, this); const { element, listener } = addControl(item, this);
this.controls.push({ element, listener }); this.controls.push({ element, listener });
} }
const { element, listener } = addControl({ type: "range", min: 1, max: 500, defaultValue: 100, property: "speedMultiplier", }, this); const { element, listener } = addControl({ type: "range", min: 1, max: 500, defaultValue: 100, property: "speedMultiplier", }, this);
this.controls.push({ element, listener }); this.controls.push({ element, listener });
} }
@ -34,7 +34,7 @@ class BaseShape {
} }
class PolyTwistColourWidth extends BaseShape { class PolyTwistColourWidth extends BaseShape {
constructor(sides, width,line_width, depth, rotation, speedMultiplier,colour1, colour2) { constructor(sides, width, line_width, depth, rotation, speedMultiplier, colour1, colour2) {
super(); super();
this.sides = sides; this.sides = sides;
this.width = width; this.width = width;
@ -47,7 +47,7 @@ class PolyTwistColourWidth extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
let out_angle = 0; let out_angle = 0;
const innerAngle = 180 - ((this.sides - 2) * 180) / this.sides; const innerAngle = 180 - ((this.sides - 2) * 180) / this.sides;
const scopeAngle = rotation - (innerAngle * Math.floor(rotation / innerAngle)); const scopeAngle = rotation - (innerAngle * Math.floor(rotation / innerAngle));
@ -64,7 +64,7 @@ class PolyTwistColourWidth extends BaseShape {
for (let i = 0; i < this.depth; i++) { for (let i = 0; i < this.depth; i++) {
const fraction = i / this.depth; const fraction = i / this.depth;
const ncolour = LerpHex(this.colour1, this.colour2, fraction); const ncolour = LerpHex(this.colour1, this.colour2, fraction);
DrawPolygon(this.sides, this.width * widthMultiplier ** i, out_angle * i + this.rotation, ncolour,this.line_width); DrawPolygon(this.sides, this.width * widthMultiplier ** i, out_angle * i + this.rotation, ncolour, this.line_width);
} }
} }
} }
@ -79,7 +79,7 @@ class FloralPhyllo extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
// var c = 24; //something to do with width. but not width // var c = 24; //something to do with width. but not width
var c = 1; //something to do with width. but not width var c = 1; //something to do with width. but not width
//dont make larger than 270 unless altering the number of colours in lerpedColours //dont make larger than 270 unless altering the number of colours in lerpedColours
@ -103,7 +103,7 @@ class Spiral1 extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
var rot = Math.round((this.sides - 2) * 180 / this.sides * 2) var rot = Math.round((this.sides - 2) * 180 / this.sides * 2)
var piv = 360 / this.sides; var piv = 360 / this.sides;
var stt = 0.5 * Math.PI - rad(rot) //+ rad(rotation); var stt = 0.5 * Math.PI - rad(rot) //+ rad(rotation);
@ -140,7 +140,7 @@ class FloralAccident extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
var rot = Math.round((this.sides - 2) * 180 / this.sides * 2) var rot = Math.round((this.sides - 2) * 180 / this.sides * 2)
var piv = 360 / this.sides; var piv = 360 / this.sides;
var stt = 0.5 * Math.PI - rad(rot) //+ rad(rotation); var stt = 0.5 * Math.PI - rad(rot) //+ rad(rotation);
@ -177,7 +177,7 @@ class FloralPhyllo_Accident extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
var c = 24; //something to do with width. but not width var c = 24; //something to do with width. but not width
for (let n = 0; n < 300; n += 1) { for (let n = 0; n < 300; n += 1) {
@ -204,7 +204,7 @@ class Nodal_expanding extends BaseShape {
} }
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
let colour_change = this.colour_change / 8 let colour_change = this.colour_change / 8
var angle = 360 / this.points * rotation var angle = 360 / this.points * rotation
@ -242,7 +242,7 @@ class Nodal extends BaseShape {
} }
// Draw_nodal(300, 100, 31, rotation, "blue"); // Draw_nodal(300, 100, 31, rotation, "blue");
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
// console.log(rotate) // console.log(rotate)
var angle = 360 / this.points * this.step var angle = 360 / this.points * this.step
ctx.beginPath(); ctx.beginPath();
@ -279,7 +279,7 @@ class Phyllotaxis extends BaseShape {
} }
// Draw_nodal(300, 100, 31, rotation, "blue"); // Draw_nodal(300, 100, 31, rotation, "blue");
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
for (let n = 0; n < this.nMax; n += 1) { for (let n = 0; n < this.nMax; n += 1) {
const ncolour = LerpHex(this.colour1, this.colour2, n / this.nMax); const ncolour = LerpHex(this.colour1, this.colour2, n / this.nMax);
// const ncolour = LerpHex(this.colour1, this.colour2, (n/this.nMax)**2); // const ncolour = LerpHex(this.colour1, this.colour2, (n/this.nMax)**2);
@ -318,7 +318,7 @@ class SquareTwist_angle extends BaseShape {
} }
// DrawSquareTwist_angle(400,0,rotation,"red") // DrawSquareTwist_angle(400,0,rotation,"red")
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
let out_angle = rotation; let out_angle = rotation;
let widthMultiplier = 1 / (2 * Math.sin(Math.PI / 180 * (130 - out_angle + 90 * Math.floor(out_angle / 90)))) + 0.5 let widthMultiplier = 1 / (2 * Math.sin(Math.PI / 180 * (130 - out_angle + 90 * Math.floor(out_angle / 90)))) + 0.5
@ -349,63 +349,79 @@ class rectangle_pattern1 extends BaseShape {
} }
// Draw_rectangle_pattern1(rotation, squares, 200, "blue"); // Draw_rectangle_pattern1(rotation, squares, 200, "blue");
draw(rotation) { draw(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
for (let z = 0; z < 360; z += 360 / this.squares) { for (let z = 0; z < 360; z += 360 / this.squares) {
this.drawSquare(z + rotation, this.width, this.colour1); this.drawSquare(z + rotation, this.width, this.colour1);
} }
} }
} }
class EyePrototype extends BaseShape { class EyePrototype extends BaseShape {
constructor(width, line_width, colour1) { constructor(width, blink_speed, draw_spiral, draw_pupil, line_width, colour1) {
super(); super();
this.width = width; this.width = width;
this.line_width = line_width; this.line_width = line_width;
this.colour1 = colour1; this.colour1 = colour1;
this.step = 0; this.step = 0;
this.speed = 8; this.speed = blink_speed;
this.opening = true; this.opening = true;
this.counter = 0; this.counter = 0;
this.points = [
[50, 250],
[450, 250],
];
this.cooldown = 0; this.cooldown = 0;
this.draw_spiral = draw_spiral;
this.draw_pupil = draw_pupil;
} }
drawEyelid(rotation) { drawEyelid(rotation) {
rotation*=(this.speedMultiplier/100) rotation *= (this.speedMultiplier / 100)
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.points[0][0], this.points[0][1]); ctx.moveTo(centerX - this.width / 2, centerY);
ctx.quadraticCurveTo(250, 250 - rotation, this.points[1][0], this.points[0][1]); ctx.quadraticCurveTo(centerX, centerY - rotation / 400 * this.width, centerX + this.width / 2, centerY);
ctx.moveTo(this.points[0][0], this.points[0][1]); ctx.moveTo(centerX - this.width / 2, centerY);
ctx.quadraticCurveTo(250, 250 + rotation, this.points[1][0], this.points[0][1]); ctx.quadraticCurveTo(centerX, centerY + rotation / 400 * this.width, centerX + this.width / 2, centerY);
ctx.stroke(); ctx.stroke();
} }
eyelidCut(step) { eyelidCut(step) {
// ctx.lineWidth = 1; // ctx.lineWidth = 1;
let squarePath = new Path2D(); let squarePath = new Path2D();
squarePath.moveTo(this.points[0][0], this.points[0][1]); squarePath.moveTo(centerX - this.width / 2, centerY);
squarePath.quadraticCurveTo(250, 250 - step, this.points[1][0], this.points[0][1]); squarePath.quadraticCurveTo(centerX, centerY - step / 400 * this.width, centerX + this.width / 2, centerY);
squarePath.moveTo(this.points[0][0], this.points[0][1]); squarePath.moveTo(centerX - this.width / 2, centerY);
squarePath.quadraticCurveTo(250, 250 + step, this.points[1][0], this.points[0][1]); squarePath.quadraticCurveTo(centerX, centerY + step / 400 * this.width, centerX + this.width / 2, centerY);
ctx.clip(squarePath); ctx.clip(squarePath);
} }
drawGrowEye(step) { drawGrowEye(step) {
console.log(step) // console.log(step)
ctx.strokeStyle = "aqua"; ctx.strokeStyle = "aqua";
ctx.beginPath(); ctx.beginPath();
ctx.lineWidth = 5; ctx.lineWidth = 5;
ctx.arc(250, 250, step, 0, 2 * Math.PI); ctx.arc(centerX, centerY, step, 0, 2 * Math.PI);
ctx.stroke(); ctx.stroke();
ctx.strokeStyle = "orange"; ctx.strokeStyle = "red";
// ctx.strokeStyle = "orange";
} }
drawCircle(step) { drawCircle(step) {
ctx.beginPath(); ctx.beginPath();
ctx.lineWidth = 5; ctx.lineWidth = 5;
ctx.arc(250, 250, step, 0, 2 * Math.PI); ctx.arc(centerX, centerY, step, 0, 2 * Math.PI);
ctx.stroke();
}
drawSpiral(step) {
let a = 1
let b = 5
ctx.moveTo(centerX, centerY);
ctx.beginPath();
for (let i = 0; i < 400; i++) {
let angle = 0.1 * i;
let x = centerX + (a + b * angle) * Math.cos(angle + step / 2);
let y = centerY + (a + b * angle) * Math.sin(angle + step / 2);
ctx.lineTo(x, y);
}
ctx.lineWidth = 3;
ctx.strokeStyle = "red";
ctx.stroke(); ctx.stroke();
} }
stepFunc() { stepFunc() {
@ -432,7 +448,7 @@ class EyePrototype extends BaseShape {
} }
draw(rotation) { draw(rotation) {
console.log(this.counter) // console.log(this.counter)
ctx.strokeStyle = "orange"; ctx.strokeStyle = "orange";
ctx.fillStyle = "black"; ctx.fillStyle = "black";
// ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); // ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
@ -441,22 +457,26 @@ class EyePrototype extends BaseShape {
// let newPath = new Path2D(); // let newPath = new Path2D();
// newPath.arc(150, 75, 75, 0, 2 * Math.PI); // newPath.arc(150, 75, 75, 0, 2 * Math.PI);
ctx.beginPath(); // ctx.beginPath();
ctx.rect(100, 100, 300, 300); // ctx.rect(centerX-300/2, centerY-300/2, 300, 300);
ctx.stroke(); // ctx.stroke();
this.drawEyelid(this.step); this.drawEyelid(this.step);
ctx.save(); ctx.save();
// squareCut(); // squareCut();
this.eyelidCut(this.step); this.eyelidCut(this.step);
if (this.counter % 100 == 0) { if (this.counter % 100 == 0) {
this.counter = 0; this.counter = 0;
} }
this.drawGrowEye(100 + this.counter); // this.drawGrowEye(this.width/4 + this.counter);
this.drawCircle(100); if(this.draw_spiral){
this.drawSpiral(rotation)
}
if(this.draw_pupil){
this.drawCircle(this.width/4);
}
ctx.restore(); ctx.restore();

37
webGl/New/index.html Normal file
View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL Template</title>
<style>
/* Set canvas to occupy the full width and height of the window */
canvas {
display: block;
width: 800px;
height: 800px;
margin: 0 560px;
padding: 0;
}
.canvas2d {
position: absolute !important;
top: 0px;
left: 0px;
}
body{
margin:0
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<canvas id="canvas2d" class="canvas2d"></canvas>
<script src="index.js">
</script>
</body>
</html>

194
webGl/New/index.js Normal file
View File

@ -0,0 +1,194 @@
// Get the canvas element and create a WebGL context
const canvas = document.getElementById('canvas');
const canvas2d = document.getElementById('canvas2d');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
let ctx = canvas2d.getContext("2d");
ctx.canvas.width = 800;
ctx.canvas.height = 800;
// Check if WebGL is available
if (!gl) {
alert('WebGL not supported in your browser.');
} else {
// Set the canvas size and WebGL viewport
canvas.width = 800;
canvas.height = 800;
let centerX = ctx.canvas.width / 2;
let centerY = ctx.canvas.height / 2;
gl.viewport(0, 0, canvas.width, canvas.height);
// Define the vertex shader source code
const glsl = x => x;
const vertexShaderSource = glsl`
attribute vec2 position;
uniform float u_rotation;
uniform vec2 u_pos;
void main() {
float centerX = 0.0;
float centerY = 0.0;
float xPos = position.x;
float yPos = position.y;
float x = xPos * cos(u_rotation) - yPos * sin(u_rotation);
float y = yPos * cos(u_rotation) + xPos * sin(u_rotation);
gl_Position = vec4(x+u_pos.x , y+u_pos.y , 0, 1);
}
`;
// Define the fragment shader source code
const fragmentShaderSource = `
precision mediump float;
uniform vec4 fColor;
void main() {
gl_FragColor = fColor;
}
`;
// Create and compile the vertex and fragment shaders
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// Create a program, attach the shaders, and link the program
const program = createProgram(gl, vertexShader, fragmentShader);
// Get the attribute and uniform locations
const positionAttributeLocation = gl.getAttribLocation(program, 'position');
const positionLocalAttributeLocation = gl.getUniformLocation(program, 'u_pos');
const rotationUniformLocation = gl.getUniformLocation(program, 'u_rotation');
const fColorLocation = gl.getUniformLocation(program, "fColor");
// Create a buffer to store vertex positions
const positionBuffer = gl.createBuffer();
function polyPoints(sides) {
let pointsArr = [];
let width = 1;
let rotation = 0
pointsArr.push(width * Math.cos((rotation * Math.PI) / 180));
pointsArr.push(width * Math.sin((rotation * Math.PI) / 180))
for (let i = 0; i < sides; i++) {
pointsArr.push(width * Math.cos((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180))
pointsArr.push(width * Math.sin((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180))
}
return pointsArr
}
function rad(degrees) {
var pi = Math.PI;
return degrees * (pi / 180);
}
// Function to create and compile a shader
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
return shader;
}
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
// Function to create a program and link shaders
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
return program;
}
console.error(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
// Function to draw the scene
let prevTime = 0
function drawScene(time) {
// Convert time to seconds
// console.log(time - prevTime)
prevTime = time
time *= 0.001;
// Clear the canvas with a black background
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Use the shader program
gl.useProgram(program);
// Enable the position attribute
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
// Create a buffer to store vertex positions
let blue = [0.17, 0.49, 0.85] //blue
let green = [0.17, 0.85, 0.46] //green
let pink = [0.96, 0.24, 0.86] //green
render_clear();
for (let i = 0; i < 10000; i++) {
DrawPolygon(4, 400, (0+time)*i*0.1, "Crimson")
// drawPoly(4, time * i * 0.001, blue, 0, 0)
}
Draw_center()
drawCircle()
// console.log(time)
// Request the next frame to be drawn
requestAnimationFrame(drawScene);
}
const positions1 = polyPoints(4)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions1), gl.STATIC_DRAW);
function drawPoly(sides, speed, colour, x, y) {
gl.uniform1f(rotationUniformLocation, speed);
gl.uniform4f(fColorLocation, colour[0], colour[1], colour[2], 1);
gl.uniform2f(positionLocalAttributeLocation, x, y);
gl.drawArrays(gl.LINE_LOOP, 0, positions1.length / 2);
}
// Start rendering the scene
requestAnimationFrame(drawScene);
function Draw_center() {
ctx.beginPath();
ctx.moveTo(centerX - 400, centerY);
ctx.lineTo(centerX + 400, centerY);
ctx.moveTo(centerX, centerY - 400);
ctx.lineTo(centerX, centerY + 400);
ctx.strokeStyle = "green";
ctx.stroke();
// console.log("drawn center")
}
function drawCircle() {
ctx.beginPath();
ctx.arc(centerX, centerY, 400, 0, 2 * Math.PI, false);
ctx.strokeStyle = "green";
ctx.stroke();
}
function DrawPolygon(sides, width, rotation, colour) {
ctx.beginPath();
ctx.moveTo(
centerX + width * Math.cos((rotation * Math.PI) / 180),
centerY + width * Math.sin((rotation * Math.PI) / 180)
);
for (var i = 1; i <= sides; i += 1) {
ctx.lineTo(
centerX + width * Math.cos((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180),
centerY + width * Math.sin((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180)
);
}
ctx.strokeStyle = colour;
ctx.lineWidth = 1;
ctx.stroke();
}
function render_clear() {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "rgb(0,0,0,0)";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
}
}

View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL Template</title>
<style>
/* Set canvas to occupy the full width and height of the window */
canvas {
display: block;
width: 800px;
height: 800px;
margin: 0 560px;
padding: 0;
}
.canvas2d {
position: absolute !important;
top: 0px;
left: 0px;
}
body{
margin:0
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<canvas id="canvas2d" class="canvas2d"></canvas>
<script src="index.js">
</script>
</body>
</html>

204
webGl/sams_webgl/index.js Normal file
View File

@ -0,0 +1,204 @@
// Get the canvas element and create a WebGL context
const canvas = document.getElementById('canvas');
const canvas2d = document.getElementById('canvas2d');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
let ctx = canvas2d.getContext("2d");
ctx.canvas.width = 800;
ctx.canvas.height = 800;
// Check if WebGL is available
if (!gl) {
alert('WebGL not supported in your browser.');
} else {
// Set the canvas size and WebGL viewport
canvas.width = 800;
canvas.height = 800;
let centerX = ctx.canvas.width / 2;
let centerY = ctx.canvas.height / 2;
gl.viewport(0, 0, canvas.width, canvas.height);
// Define the vertex shader source code
const vertexShaderSource = `
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
attribute vec2 position;
uniform float u_rotation;
uniform vec2 u_pos;
varying vec4 vColor;
void main() {
vColor = vec4(hsv2rgb(vec3(u_rotation, 0.5+pow(position.y+0.4, 10.0), 1.0)), 1.0);
float centerX = 0.0;
float centerY = 0.0;
float xPos = position.x;
float yPos = position.y;
float rot_cos = cos(u_rotation);
float rot_sin = sin(u_rotation);
float x = xPos * rot_cos - yPos * rot_sin;
float y = yPos * rot_cos + xPos * rot_sin;
gl_Position = vec4(x+u_pos.x , y+u_pos.y , 0, 1);
}
`;
// Define the fragment shader source code
const fragmentShaderSource = `
precision mediump float;
varying vec4 vColor;
uniform vec4 fColor;
void main() {
gl_FragColor = vColor;
}
`;
// Create and compile the vertex and fragment shaders
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// Create a program, attach the shaders, and link the program
const program = createProgram(gl, vertexShader, fragmentShader);
// Get the attribute and uniform locations
const positionAttributeLocation = gl.getAttribLocation(program, 'position');
// const positionAttributeLocation1 = gl.getAttribLocation(program, 'u_pos');
const rotationUniformLocation = gl.getUniformLocation(program, 'u_rotation');
const fColorLocation = gl.getUniformLocation(program, "fColor");
// Create a buffer to store vertex positions
const positionBuffer = gl.createBuffer();
// Bind the buffer and send the vertex positions to the GPU
function polyPoints(sides) {
let pointsArr = [];
let width = 1;
let rotation = 0
pointsArr.push(width * Math.cos((rotation * Math.PI) / 180));
pointsArr.push(width * Math.sin((rotation * Math.PI) / 180))
for (let i = 0; i < sides; i++) {
pointsArr.push(width * Math.cos((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180))
pointsArr.push(width * Math.sin((i * 2 * Math.PI) / sides + (rotation * Math.PI) / 180))
}
return pointsArr
}
function rad(degrees) {
var pi = Math.PI;
return degrees * (pi / 180);
}
// Function to create and compile a shader
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
return shader;
}
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
// Function to create a program and link shaders
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
return program;
}
console.error(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
// Function to draw the scene
let prevTime = 0
function drawScene(time) {
// Convert time to seconds
// console.log(time - prevTime)
prevTime = time
time *= 0.001;
// Clear the canvas with a black background
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Use the shader program
gl.useProgram(program);
// Enable the position attribute
// Create a buffer to store vertex positions
let blue = [0.17, 0.49, 0.85] //blue
let green = [0.17, 0.85, 0.46] //green
let pink = [0.96, 0.24, 0.86] //green
// drawPoly(3, time * 1, blue, 0, 0)
// drawPoly(3, time * 0.8, pink, 0.35, 0.35)
// drawPoly(5,time*0.6)
// drawPoly(6,time*0.4)
// drawPoly(7,time*0.2)
//
// prepare the gl state for the draw (can be here as drawPoly gets called multiple times with the same state)
// This could be improved by using a VAO to get the gpu to run over the for loop for you
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
for (let i = 0; i < 100; i++) {
drawPoly(4, time * i * 0.001, blue, 0, 0)
}
Draw_center()
drawCircle()
// console.log(time)
// Request the next frame to be drawn
requestAnimationFrame(drawScene);
}
function drawPoly(sides, speed, colour, x, y) {
gl.uniform1f(rotationUniformLocation, speed);
gl.uniform4f(fColorLocation, colour[0], colour[1], colour[2], 1);
gl.uniform2f(gl.getUniformLocation(program, 'u_pos'), x, y);
const positions = polyPoints(sides)
// const positionBuffer1 = gl.createBuffer();
// Assume the buffers are already bound
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.DYNAMIC_DRAW);
gl.drawArrays(gl.LINE_LOOP, 0, positions.length / 2);
}
// Start rendering the scene
requestAnimationFrame(drawScene);
function Draw_center() {
ctx.beginPath();
ctx.moveTo(centerX - 400, centerY);
ctx.lineTo(centerX + 400, centerY);
ctx.moveTo(centerX, centerY - 400);
ctx.lineTo(centerX, centerY + 400);
ctx.strokeStyle = "green";
ctx.stroke();
// console.log("drawn center")
}
function drawCircle() {
ctx.beginPath();
ctx.arc(centerX, centerY, 400, 0, 2 * Math.PI, false);
ctx.strokeStyle = "green";
ctx.stroke();
}
}