Eye prototype work
This commit is contained in:
parent
687c44f22e
commit
bc01c0e0c9
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,56 +356,72 @@ class rectangle_pattern1 extends BaseShape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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();
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue