canvas实现webgl线圈绕组动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现webgl线圈绕组动画效果代码,可通过dat.gui更换图形,选择圆圈、星星等图形样式、还可更改背景颜色。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body { background-color: #fff; margin: 0; overflow: hidden; } canvas { position: absolute; background-color: #999; width: 100%; height: 100%; vertical-align: middle; display:inline-block; } </style> </head> <body > <canvas id="canvas"></canvas> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script> <script > /* * The winding number of a point describes how many full revolutions a curve makes around it. * Open curves produce interesting visuals. We discretise parametric curves into linear * segments and find the signed angle between the vectors connecting a point to the segment. * The sum of these angles, divided by 2PI radians, gives the winding number. * * Based on: * https://en.wikipedia.org/wiki/Winding_number * [1] https://igl.ethz.ch/projects/winding-number/ * https://twitter.com/keenanisalive/status/1448036393012322313 * https://www.shadertoy.com/view/Wddyz2 * */ let canvas = document.getElementById("canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; // MSAA let multiplier = 2.0; var AA = true; // Initialize the GL context let gl = canvas.getContext('webgl'); if (!gl) { console.error("Unable to initialize WebGL."); } let time = 0.0; let scene = 0; let palette = 0; let sceneNames = ["Circle", "Heart", "Star", "Infinity"]; let paletteNames = ["Grayscale", "Rainbow", "Red", "Blue"]; let sceneSelector = { scene: "Circle" }; let paletteSelector = { palette: "Rainbow" }; setScene(sceneSelector.scene); setPalette(paletteSelector.palette); //************* GUI *************** let gui = new dat.GUI(); gui.add(sceneSelector, 'scene').options(sceneNames).onChange(name => {setScene(name);}); gui.add(paletteSelector, 'palette').options(paletteNames).onChange(name => {setPalette(name);}); gui.add(this, 'AA').onChange(b => {b ? multiplier = 2 : multiplier = 1;onWindowResize();}).listen(); gui.close(); //******** Shader sources ********* let vertexSource = ` attribute vec2 position; void main() { // Screenspace position of vertices can use the data passed from the CPU // Set z-component to 0 gl_Position = vec4(position, 0.0, 1.0); } `; //Replace with GLSL fragment shader code let fragmentSource = ` precision highp float; uniform vec2 resolution; uniform float time; uniform float u_scene; uniform float u_palette; #define PI 3.1415926536 #define TWO_PI 6.2831853072 // https://math.stackexchange.com/questions/3020095/signed-angle-in-plane: // "the ratio of the cross product and scalar product is the tangent of the angle" // From [1]: "The tangent of the signed angle between a and b is det([ab]) / dot(ab)" float signedAngle(vec2 a, vec2 b){ // atan(y, x) returns the angle whose arctangent is y / x. Value in [-pi, pi] return atan(a.x*b.y - a.y*b.x, dot(a, b)); } // https://iquilezles.org/articles/palettes/ vec3 getColour(float t, int palette){ if(palette == 0){ // Black and white return vec3(-0.5 * t + 0.45); } vec3 a; vec3 b; vec3 c; vec3 d; if(palette == 1){ // Pastel rainbow // Animated t *= 0.45; t += 0.1 * time; a = vec3(0.65); b = 1.0 - a; c = vec3(1.0,1.0,1.0); d = vec3(0.15,0.5,0.75); }else if(palette == 2){ // Red and purple t *= -0.3; t += 0.65; a = vec3(0.55, 0.5, 0.7); b = 1.0-a; .........完整代码请登录后点击上方下载按钮下载查看
网友评论0