分享一个鬼~

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

先看效果:
在这里插入图片描述
上源码:

import GUI from "https://cdn.jsdelivr.net/npm/lil-gui@0.18.2/+esm"const canvasEl = document.querySelector("#ghost");const mouseThreshold = .1;
const devicePixelRatio = Math.min(window.devicePixelRatio, 2);const mouse = {x: .3 * window.innerWidth,y: .3 * window.innerHeight,tX: .25 * window.innerWidth,tY: .45 * window.innerHeight,moving: false,controlsPadding: 0
}const params = {size: .1,tail: {dotsNumber: 25,spring: 1.4,friction: .3,maxGravity: 50,gravity: 25,},smile: 1,mainColor: [.98, .96, .96],borderColor: [.2, .5, .7],isFlatColor: false,
};const textureEl = document.createElement("canvas");
const textureCtx = textureEl.getContext("2d");
const pointerTrail = new Array(params.tail.dotsNumber);
let dotSize = (i) => params.size * window.innerHeight * (1. - .2 * Math.pow(3. * i / params.tail.dotsNumber - 1., 2.));
for (let i = 0; i < params.tail.dotsNumber; i++) {pointerTrail[i] = {x: mouse.x,y: mouse.y,vx: 0,vy: 0,opacity: .04 + .3 * Math.pow(1 - i / params.tail.dotsNumber, 4),bordered: .6 * Math.pow(1 - i / pointerTrail.length, 1),r: dotSize(i)}
}let uniforms;
const gl = initShader();
createControls();window.addEventListener("resize", resizeCanvas);
resizeCanvas();
render();window.addEventListener("mousemove", e => {updateMousePosition(e.clientX, e.clientY);
});
window.addEventListener("touchmove", e => {updateMousePosition(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
});
window.addEventListener("click", e => {updateMousePosition(e.clientX, e.clientY);
});let movingTimer = setTimeout(() => mouse.moving = false, 300);function updateMousePosition(eX, eY) {mouse.moving = true;if (mouse.controlsPadding < 0) {mouse.moving = false;}clearTimeout(movingTimer);movingTimer = setTimeout(() => {mouse.moving = false;}, 300);mouse.tX = eX;const size = params.size * window.innerHeight;eY -= .6 * size;mouse.tY = eY > size ? eY : size;mouse.tY -= mouse.controlsPadding;
}function initShader() {const vsSource = document.getElementById("vertShader").innerHTML;const fsSource = document.getElementById("fragShader").innerHTML;const gl = canvasEl.getContext("webgl") || canvasEl.getContext("experimental-webgl");if (!gl) {alert("WebGL is not supported by your browser.");}function createShader(gl, sourceCode, type) {const shader = gl.createShader(type);gl.shaderSource(shader, sourceCode);gl.compileShader(shader);if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));gl.deleteShader(shader);return null;}return shader;}const vertexShader = createShader(gl, vsSource, gl.VERTEX_SHADER);const fragmentShader = createShader(gl, fsSource, gl.FRAGMENT_SHADER);function createShaderProgram(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)) {console.error("Unable to initialize the shader program: " + gl.getProgramInfoLog(program));return null;}return program;}const shaderProgram = createShaderProgram(gl, vertexShader, fragmentShader);uniforms = getUniforms(shaderProgram);function getUniforms(program) {let uniforms = [];let uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);for (let i = 0; i < uniformCount; i++) {let uniformName = gl.getActiveUniform(program, i).name;uniforms[uniformName] = gl.getUniformLocation(program, uniformName);}return uniforms;}const vertices = new Float32Array([-1., -1., 1., -1., -1., 1., 1., 1.]);const vertexBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);gl.useProgram(shaderProgram);const positionLocation = gl.getAttribLocation(shaderProgram, "a_position");gl.enableVertexAttribArray(positionLocation);gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);const canvasTexture = gl.createTexture();gl.bindTexture(gl.TEXTURE_2D, canvasTexture);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);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.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureEl);gl.uniform1i(uniforms.u_texture, 0);gl.uniform1f(uniforms.u_size, params.size);gl.uniform3f(uniforms.u_main_color, params.mainColor[0], params.mainColor[1], params.mainColor[2]);gl.uniform3f(uniforms.u_border_color, params.borderColor[0], params.borderColor[1], params.borderColor[2]);return gl;
}function updateTexture() {textureCtx.fillStyle = 'black';textureCtx.fillRect(0, 0, textureEl.width, textureEl.height);pointerTrail.forEach((p, pIdx) => {if (pIdx === 0) {p.x = mouse.x;p.y = mouse.y;} else {p.vx += (pointerTrail[pIdx - 1].x - p.x) * params.tail.spring;p.vx *= params.tail.friction;p.vy += (pointerTrail[pIdx - 1].y - p.y) * params.tail.spring;p.vy *= params.tail.friction;p.vy += params.tail.gravity;p.x += p.vx;p.y += p.vy;}const grd = textureCtx.createRadialGradient(p.x, p.y, p.r * p.bordered, p.x, p.y, p.r);grd.addColorStop(0, 'rgba(255, 255, 255, ' + p.opacity + ')');grd.addColorStop(1, 'rgba(255, 255, 255, 0)');textureCtx.beginPath();textureCtx.fillStyle = grd;textureCtx.arc(p.x, p.y, p.r, 0, Math.PI * 2);textureCtx.fill();});
}function render() {const currentTime = performance.now();gl.uniform1f(uniforms.u_time, currentTime);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.clear(gl.COLOR_BUFFER_BIT);gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);if (mouse.moving) {params.smile -= .05;params.smile = Math.max(params.smile, -.1);params.tail.gravity -= 10 * params.size;params.tail.gravity = Math.max(params.tail.gravity, 0);} else {params.smile += .01;params.smile = Math.min(params.smile, 1);if (params.tail.gravity > 30 * params.size) {params.tail.gravity = (30 + 9 * (1 + Math.sin(.002 * currentTime))) * params.size;} else {params.tail.gravity += params.size;}}mouse.x += (mouse.tX - mouse.x) * mouseThreshold;mouse.y += (mouse.tY - mouse.y) * mouseThreshold;gl.uniform1f(uniforms.u_smile, params.smile);gl.uniform2f(uniforms.u_pointer, mouse.x / window.innerWidth, 1. - mouse.y / window.innerHeight);gl.uniform2f(uniforms.u_target_pointer, mouse.tX / window.innerWidth, 1. - mouse.tY / window.innerHeight);updateTexture();gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureEl);requestAnimationFrame(render);
}function resizeCanvas() {canvasEl.width = window.innerWidth * devicePixelRatio;canvasEl.height = window.innerHeight * devicePixelRatio;textureEl.width = window.innerWidth;textureEl.height = window.innerHeight;gl.viewport(0, 0, canvasEl.width, canvasEl.height);gl.uniform1f(uniforms.u_ratio, canvasEl.width / canvasEl.height);for (let i = 0; i < params.tail.dotsNumber; i++) {pointerTrail[i].r = dotSize(i);}
}function createControls() {const gui = new GUI();gui.add(params, "size", .02, .3, .01).onChange(v => {for (let i = 0; i < params.tail.dotsNumber; i++) {pointerTrail[i].r = dotSize(i);}gl.uniform1f(uniforms.u_size, params.size);});gui.addColor(params, "mainColor").onChange(v => {gl.uniform3f(uniforms.u_main_color, v[0], v[1], v[2]);});const borderColorControl = gui.addColor(params, "borderColor").onChange(v => {gl.uniform3f(uniforms.u_border_color, v[0], v[1], v[2]);});gui.add(params, "isFlatColor").onFinishChange(v => {borderColorControl.disable(v);gl.uniform1f(uniforms.u_flat_color, v ? 1 : 0);});const controlsEl = document.querySelector(".lil-gui");controlsEl.addEventListener("mouseenter", () => {mouse.controlsPadding = -controlsEl.getBoundingClientRect().height;});controlsEl.addEventListener("mouseleave", () => {mouse.controlsPadding = 0;});
}
<div class="page">WebGL Ghost Cursor
</div><canvas id="ghost"></canvas><script type="x-shader/x-fragment" id="vertShader">precision mediump float;varying vec2 vUv;attribute vec2 a_position;void main() {vUv = .5 * (a_position + 1.);gl_Position = vec4(a_position, 0.0, 1.0);}
</script><script type="x-shader/x-fragment" id="fragShader">precision mediump float;varying vec2 vUv;uniform float u_time;uniform float u_ratio;uniform float u_size;uniform vec2 u_pointer;uniform float u_smile;uniform vec2 u_target_pointer;uniform vec3 u_main_color;uniform vec3 u_border_color;uniform float u_flat_color;uniform sampler2D u_texture;#define TWO_PI 6.28318530718#define PI 3.14159265358979323846vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }float snoise(vec2 v) {const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);vec2 i = floor(v + dot(v, C.yy));vec2 x0 = v - i + dot(i, C.xx);vec2 i1;i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);vec4 x12 = x0.xyxy + C.xxzz;x12.xy -= i1;i = mod289(i);vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);m = m*m;m = m*m;vec3 x = 2.0 * fract(p * C.www) - 1.0;vec3 h = abs(x) - 0.5;vec3 ox = floor(x + 0.5);vec3 a0 = x - ox;m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);vec3 g;g.x = a0.x * x0.x + h.x * x0.y;g.yz = a0.yz * x12.xz + h.yz * x12.yw;return 130.0 * dot(m, g);}vec2 rotate(vec2 v, float angle) {float r_sin = sin(angle);float r_cos = cos(angle);return vec2(v.x * r_cos - v.y * r_sin, v.x * r_sin + v.y * r_cos);}float eyes(vec2 uv) {uv.y -= .5;uv.x *= 1.;uv.y *= .8;uv.x = abs(uv.x);uv.y += u_smile * .3 * pow(uv.x, 1.3);uv.x -= (.6 + .2 * u_smile);float d = clamp(length(uv), 0., 1.);return 1. - pow(d, .08);}float mouth(vec2 uv) {uv.y += 1.5;uv.x *= (.5 + .5 * abs(1. - u_smile));uv.y *= (3. - 2. * abs(1. - u_smile));uv.y -= u_smile * 4. * pow(uv.x, 2.);float d = clamp(length(uv), 0., 1.);return 1. - pow(d, .07);}float face(vec2 uv, float rotation) {uv = rotate(uv, rotation);uv /= (.27 * u_size);float eyes_shape = 10. * eyes(uv);float mouth_shape = 20. * mouth(uv);float col = 0.;col = mix(col, 1., eyes_shape);col = mix(col, 1., mouth_shape);return col;}void main() {vec2 point = u_pointer;point.x *= u_ratio;vec2 uv = vUv;uv.x *= u_ratio;uv -= point;float texture = texture2D(u_texture, vec2(vUv.x, 1. - vUv.y)).r;float shape = texture;float noise = snoise(uv * vec2(.7 / u_size, .6 / u_size) + vec2(0., .0015 * u_time));noise += 1.2;noise *= 2.1;noise += smoothstep(-.8, -.2, (uv.y) / u_size);float face = face(uv, 5. * (u_target_pointer.x - u_pointer.x));shape -= face;shape *= noise;vec3 border = (1. - u_border_color);border.g += .2 * sin(.005 * u_time);border *= .5;vec3 color = u_main_color;color -= (1. - u_flat_color) * border * smoothstep(.0, .01, shape);shape = u_flat_color * smoothstep(.8, 1., shape) + (1. - u_flat_color) * shape;color *= shape;gl_FragColor = vec4(color, shape);}
</script>
body, html {margin: 0;padding: 0;overflow: hidden;background-color: #2C3E50;
}canvas#ghost {position: fixed;top: 0;left: 0;display: block;width: 100%;z-index: 10000;pointer-events: none;
}.page {min-height: 100vh;display: flex;align-items: center;justify-content: center;color: white;text-align: center;font-size: 4vw;text-shadow: 0 0 5px #000000;
}.lil-gui {--width: 300px;max-width: 90%;--widget-height: 20px;font-size: 15px;--input-font-size: 15px;--padding: 10px;--spacing: 10px;--slider-knob-width: 5px;--background-color: rgba(5, 0, 15, .8);--widget-color: rgba(255, 255, 255, .3);--focus-color: rgba(255, 255, 255, .4);--hover-color: rgba(255, 255, 255, .5);--font-family: monospace;z-index: 1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/217392.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分查找之红蓝二分查找

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

鸿蒙原生应用/元服务开发-AGC分发如何上架HarmonyOS应用

一、上架整体流程 二、上架HarmonyOS应用 获取到HarmonyOS应用软件包后&#xff0c;开发者可将应用提交至AGC申请上架。上架成功后&#xff0c;用户即可在华为应用市场搜索获取开发者的HarmonyOS应用。 配置应用信息 1.登录AppGallery Connect&#xff0c;选择“我的应用”。…

CCC联盟——UWB MAC(二)

在上一篇文章中对CCC联盟UWB MAC框架进行了介绍&#xff0c;在本文中&#xff0c;将MAC层的时间网格进行简单介绍。 2、MAC时间网格&#xff08;Time Grid) DK UWB测距协议属于一对多&#xff08;One to Many, O2M)测距协议。发起者&#xff0c;每次发送4帧&#xff0c;接收N帧…

学习Pandas 二(Pandas缺失值处理、数据离散化、合并、交叉表与透视表、分组与聚合)

文章目录 六、高级处理-缺失值处理6.1 检查是否有缺失值6.2 缺失值处理6.3 不是缺失值NaN&#xff0c;有默认标记的 七、高级处理-数据离散化7.1 什么是数据的离散化7.2 为什么要离散化7.3 如何实现数据的离散化 八、高级处理-合并8.1 pc.concat实现合并&#xff0c;按方向进行…

Linux:Ubuntu虚拟机安装详解:VMware下的逐步指南

目录 1. centOS系统 2. ubuntu系统 1. 下载Ubuntu映像 step1 step2 step3 2. 新建虚拟机 step1 step2 Step3 step4 step5 step6 内存 内核 映像 显示 网络 3. 网络配置 NAT模式 本机IP获取 ​编辑 bridge模式 4. 开启虚拟机 5. 虚拟机常用配置 语言 …

为什么,word文件在只读模式下,仍然能编辑?

Word文档设置了只读模式&#xff0c;是可以编辑的&#xff0c;但是当我们进行保存的时候就会发现&#xff0c;word提示需要重命名并选择新路径才能够保存。 这种操作&#xff0c;即使可以编辑文字&#xff0c;但是原文件是不会受到影响的&#xff0c;编辑之后的word文件会保存到…

Redis Stream消息队列

什么是Stream? Stream 实际上是一个具有消息发布/订阅功能的组件&#xff0c;也就常说的消息队列。其实这种类似于 broker/consumer(生产者/消费者)的数据结构很常见&#xff0c;比如 RabbitMQ 消息中间件、Celery 消息中间件&#xff0c;以及 Kafka 分布式消息系统等&#x…

openEuler20.03学习01-创建虚拟机

赶个时髦&#xff0c;开始学习openEuler 20.03 (LTS-SP3) 操作系统iso下载地址&#xff1a;https://repo.openeuler.openatom.cn/openEuler-20.03-LTS-SP3/ISO/x86_64/openEuler-20.03-LTS-SP3-x86_64-dvd.iso 公司有现成的vmware环境&#xff0c;创建虚拟机i测试&#xff0c…

qgis添加arcgis的mapserver

左侧浏览器-ArcGIS地图服务器-右键-新建连接 Folder: / 展开-双击图层即可

通过ros系统中websocket中发送sensor_msgs::Image数据给web端显示(三)

通过ros系统中websocket中发送sensor_msgs::Image数据给web端显示(三) 不使用base64编码方式传递 #include <ros/ros.h> #include <signal.h> #include <sensor_msgs/Image.h> #include <message_filters/subscriber.h> #include <message_filter…

leetcode中“辅助栈”类题目和“单调栈”类题目的异同

1 总结 1 栈中元素的特性 2 单调栈存在一次性连续删除多个栈顶的情况&#xff0c;但是普通的栈&#xff0c;一次只pop掉一个栈顶元素 2 LC1209. 删除字符串中的所有相邻重复项 II - 普通辅助栈 class Solution {public String removeDuplicates(String s, int k) {int ns.l…

mysql忘记密码,然后重置

数据库版本8.0.26 只针对以下情况 mysql忘记了密码&#xff0c;但是你navicat之前连接上了 解决方法&#xff1a; 第一步&#xff0c;选中mysql这个数据库&#xff0c;点击新建查询 第二步&#xff1a;重置密码 alter user rootlocalhost IDENTIFIED BY 你的密码; 然后就可…