<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>JYPSYEYE — VORTEX</title>
<style>
html,body{
margin:0;
height:100%;
background:#000;
overflow:hidden;
font-family:Arial,Helvetica,sans-serif;
}
#stars{
position:fixed;
inset:0;
width:100%;
height:100%;
z-index:0;
pointer-events:none;
}
#frame{
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
background:#000;
z-index:1;
}
#c{
display:block;
}
#counter{
position:fixed;
top:14px;
right:16px;
z-index:2;
color:#39ff14;
font-size:13px;
letter-spacing:.08em;
background:rgba(0,0,0,.55);
padding:8px 10px;
border:1px solid rgba(255,255,255,.18);
border-radius:6px;
white-space:pre;
}
</style>
</head>
<body>
<canvas id="stars"></canvas>
<div id="frame">
<canvas id="c"></canvas>
</div>
<div id="counter">VISITORS: ...</div>
<script>
fetch("https://api.countapi.xyz/hit/jypsyeye/vortex")
.then(function(res){ return res.json(); })
.then(function(data){
document.getElementById("counter").textContent = "VISITORS: " + data.value;
})
.catch(function(){
document.getElementById("counter").textContent = "VISITORS: --";
});
</script>
<script>
const starCanvas = document.getElementById("stars");
const sctx = starCanvas.getContext("2d");
let stars = [];
function resizeStars(){
const dpr = window.devicePixelRatio || 1;
starCanvas.width = Math.floor(innerWidth * dpr);
starCanvas.height = Math.floor(innerHeight * dpr);
starCanvas.style.width = "100%";
starCanvas.style.height = "100%";
sctx.setTransform(dpr,0,0,dpr,0,0);
const count = Math.floor((innerWidth * innerHeight) / 9000);
stars = [];
for(let i=0;i<count;i++){
stars.push({
x: Math.random() * innerWidth,
y: Math.random() * innerHeight,
r: Math.random() * 1.4 + 0.2,
a: Math.random() * 0.6 + 0.2,
tw: Math.random() * 1.5 + 0.3,
ph: Math.random() * Math.PI * 2
});
}
}
function drawStars(t){
sctx.clearRect(0,0,innerWidth,innerHeight);
for(let i=0;i<stars.length;i++){
const s = stars[i];
const alpha = s.a * (0.6 + 0.4 * Math.sin(t * 0.001 * s.tw + s.ph));
sctx.fillStyle = "rgba(255,255,255," + alpha + ")";
sctx.beginPath();
sctx.arc(s.x, s.y, s.r, 0, Math.PI * 2);
sctx.fill();
}
requestAnimationFrame(drawStars);
}
addEventListener("resize", resizeStars);
resizeStars();
requestAnimationFrame(drawStars);
</script>
<script>
const canvas = document.getElementById("c");
const frame = document.getElementById("frame");
const gl = canvas.getContext("webgl",{alpha:false,antialias:false});
if(!gl){
document.body.innerHTML = "WebGL not supported";
throw new Error("no webgl");
}
const ASPECT = 2.39;
const SCALE = 0.58;
function resize(){
const dpr = window.devicePixelRatio || 1;
let w = window.innerWidth * SCALE;
let h = w / ASPECT;
if(h > window.innerHeight * SCALE){
h = window.innerHeight * SCALE;
w = h * ASPECT;
}
frame.style.width = w + "px";
frame.style.height = h + "px";
canvas.width = Math.floor(w * dpr);
canvas.height = Math.floor(h * dpr);
canvas.style.width = w + "px";
canvas.style.height = h + "px";
gl.viewport(0,0,canvas.width,canvas.height);
}
addEventListener("resize", resize);
const vs = `
attribute vec2 p;
void main(){
gl_Position = vec4(p,0.0,1.0);
}
`;
const fs = `
precision mediump float;
uniform vec2 r;
uniform float t;
uniform sampler2D tex;
void main(){
vec2 p = (gl_FragCoord.xy - r * 0.5) / min(r.x,r.y);
float ang = atan(p.y,p.x) / 6.28318 + 0.5;
float dep = 1.0 / max(length(p),0.03);
float u = ang + t * 0.00004;
float v = dep * 0.10 - t * 0.000075;
vec2 uv = vec2(fract(u),fract(v));
gl_FragColor = texture2D(tex,uv);
}
`;
function compile(type,src){
const s = gl.createShader(type);
gl.shaderSource(s,src);
gl.compileShader(s);
if(!gl.getShaderParameter(s, gl.COMPILE_STATUS)){
throw new Error(gl.getShaderInfoLog(s) || "shader compile error");
}
return s;
}
const prog = gl.createProgram();
gl.attachShader(prog, compile(gl.VERTEX_SHADER,vs));
gl.attachShader(prog, compile(gl.FRAGMENT_SHADER,fs));
gl.linkProgram(prog);
if(!gl.getProgramParameter(prog, gl.LINK_STATUS)){
throw new Error(gl.getProgramInfoLog(prog) || "program link error");
}
gl.useProgram(prog);
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buf);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([
-1,-1,
1,-1,
-1, 1,
-1, 1,
1,-1,
1, 1
]),gl.STATIC_DRAW);
const loc = gl.getAttribLocation(prog,"p");
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc,2,gl.FLOAT,false,0,0);
const tex = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);
gl.uniform1i(gl.getUniformLocation(prog,"tex"),0);
const rLoc = gl.getUniformLocation(prog,"r");
const tLoc = gl.getUniformLocation(prog,"t");
const img = new Image();
img.src = "images/BROTHERHOOD.jpg";
img.onload = function(){
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGB,
gl.RGB,
gl.UNSIGNED_BYTE,
img
);
resize();
requestAnimationFrame(draw);
};
img.onerror = function(){
document.getElementById("counter").textContent = "VISITORS: IMAGE ERROR";
};
function draw(time){
gl.uniform2f(rLoc, canvas.width, canvas.height);
gl.uniform1f(tLoc, time);
gl.drawArrays(gl.TRIANGLES,0,6);
requestAnimationFrame(draw);
}
resize();
</script>
</body>
</html>