js实现创意液体融合波纹动画效果代码

代码语言:html

所属分类:动画

代码描述:js实现创意液体融合波纹动画效果代码

代码标签: 液体 融合 波纹

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">

  
  
  
  
<style>
body {
  background-color: #000;
  margin: 0;
  overflow: hidden;
  background-repeat: no-repeat;
}
canvas {
  position : absolute;
}
</style>



</head>

<body  >
  

  
 <script >
"use strict";

let canv, gl;
let animState;
let maxx, maxy;
let midx, midy;

let widthHandle, heightHandle;
let pHandle, f;
let p = [];

const ORDER = 10;

const mrandom = Math.random;
const mfloor = Math.floor;
const mround = Math.round;
const mceil = Math.ceil;
const mabs = Math.abs;
const mmin = Math.min;
const mmax = Math.max;

const mPI = Math.PI;
const mPIS2 = Math.PI / 2;
const m2PI = Math.PI * 2;
const msin = Math.sin;
const mcos = Math.cos;
const matan2 = Math.atan2;

const mhypot = Math.hypot;
const msqrt = Math.sqrt;

//-----------------------------------------------------------------------------
// miscellaneous functions
//-----------------------------------------------------------------------------

function alea(min, max) {
  // random number [min..max[ . If no max is provided, [0..min[

  if (typeof max == 'undefined') return min * mrandom();
  return min + (max - min) * mrandom();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function intAlea(min, max) {
  // random integer number [min..max[ . If no max is provided, [0..min[

  if (typeof max == 'undefined') {
    max = min;min = 0;
  }
  return mfloor(min + (max - min) * mrandom());
} // intAlea

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function distance(p0, p1) {

  /* distance between points */

  return mhypot(p0[0] - p1[0], p0[1] - p1[1]);

} // function distance

/*	============================================================================
	This is based upon Johannes Baagoe's carefully designed and efficient hash
	function for use with JavaScript.  It has a proven "avalanche" effect such
	that every bit of the input affects every bit of the output 50% of the time,
	which is good.	See: http://baagoe.com/en/RandomMusings/hash/avalanche.xhtml
	============================================================================
*/
/* This function returns a hash function depending on a seed.

if no seed is provided (or a falsy value), Math.random() is used.
The returned function always returns the same number in the range [0..1[ for the
same value of the argument. This argument may be a String or a Number or anything else
which can be 'toStringed'
Two returned functions obtained with two equal seeds are equivalent.
*/

function hashFunction(seed) {
  let n0 = 0xefc8249d;
  let n = n0;
  mash(seed || Math.random()); // pre-compute n for seed
  n0 = n; //

  function mash(data) {
    data = data.toString() + 'U';
    n = n0;
    for (let i = 0; i < data.length; i++) {
      n += data.charCodeAt(i);
      var h = 0.02519603282416938 * n;
      n = h >>> 0;
      h -= n;
      h *= n;
      n = h >>> 0;
      h -= n;
      n += h * 0x100000000; // 2^32
    } // for
    return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
  } // mash
  return mash;
} // hashFunction(seed)

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function Noise1D(period, min = 0, max = 1, hash) {
  /* returns a 1D noise function.
     the (mandatory) hash function must return a value between 0 and 1. The hash function
     will be called with an integer number for a parameter.
    the returned function takes one parameter, and will always return the same value if called with the same parameter
    period should be > 1. The bigger period is, the smoother the output noise is
  
  suggestion : the hash parameter could be a function returned from a call to hashFunction above
  
  */

  let currx, y0, y1; // cached valued, to reduce number of calls to 'hash'
  let phase = hash(0); // to shift the phase of different generators between each other;

  return function (x) {
    let xx = x / period + phase;
    let intx = mfloor(xx);

    if (intx - 1 === currx) {// next integer interval
      ++currx;
      y0 = y1;
      y1 = min + (max - min) * hash(currx + 1);
    } else if (intx !== currx) {// unrelated interval
      currx = intx;
      y0 = min + (max - min) * hash(currx);
      y1 = min + (max - min) * hash(currx + 1);
    }
    let frac = xx - currx;
    let z = (3 - 2 * frac) * frac * frac;
    return z * y1 + (1 - z) * y0;
  };
} // Noise1D
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

//************** Shader sources **************
let vertexSource = `
attribute vec2 position;


void main() {
  gl_Position = vec4(position, 0.0, 1.0);
}
`;

let fragmentSource = `

  precision mediump float;

#define ORDER ${2 * ORDER}

  uniform float width;
  uniform float height;

  uniform vec2 p[ORDER];

  vec2 iResolution;
  vec2 z, znum, zden;


vec2 mult(vec2 z1, vec2 z2) {
  return vec2(z1.x * z2.x - z1.y * z2.y, z1.x * z2.y + z1.y * z2.x);
} // dmult

vec2 div( vec2 z1, vec2 z2) {
  return vec2(z1.x * z2.x + z1.y * z2.y, z1.y * z2.x - z1.x * z2.y) / (z2.x * z2.x + z2.y * z2.y);
} // div

void main(){

  iResolution = vec2(width, height);

// z = -1...+1 on shortest dimension

  z = (gl_FragCoord.xy - 0.5 * iResolution ) / min(width, height) * 2.0 ;


// calculate (z-p1) / (z-p2) * (z-p3) / (z-p4)...

  znum = z - p[0];
  zden = z - p[1];
  for (int k = 2; k < ORDER; k += 2) {
    znum = mult(znum, z - p[k]);
    zden = mult(zden, z - p[k + 1]);
  }
  z = div(znum, zden);

// take imaginary part of log :
  float s =  atan(z.x + length(z), z.y) / 3.14159265; // thanks to wikipedia!

  gl_F.........完整代码请登录后点击上方下载按钮下载查看

网友评论0