$(function(){
//粒子
////////////////////////////粒子
class shaderprogram {
constructor( holder, options = {} ) {
options = object.assign( {
antialias: false,
depthtest: false,
mousemove: false,
autosize: true,
side: 'front',
vertex: `
precision highp float;
attribute vec4 a_position;
attribute vec4 a_color;
uniform float u_time;
uniform vec2 u_resolution;
uniform vec2 u_mousemove;
uniform mat4 u_projection;
varying vec4 v_color;
void main() {
gl_position = u_projection * a_position;
gl_pointsize = (10.0 / gl_position.w) * 100.0;
v_color = a_color;
}`,
fragment: `
precision highp float;
uniform sampler2d u_texture;
uniform int u_hastexture;
varying vec4 v_color;
void main() {
if ( u_hastexture == 1 ) {
gl_fragcolor = v_color * texture2d(u_texture, gl_pointcoord);
} else {
gl_fragcolor = v_color;
}
}`,
uniforms: {},
buffers: {},
camera: {},
texture: null,
onupdate: ( () => {} ),
onresize: ( () => {} ),
}, options )
const uniforms = object.assign( {
time: { type: 'float', value: 0 },
hastexture: { type: 'int', value: 0 },
resolution: { type: 'vec2', value: [ 0, 0 ] },
mousemove: { type: 'vec2', value: [ 0, 0 ] },
projection: { type: 'mat4', value: [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] },
}, options.uniforms )
const buffers = object.assign( {
position: { size: 3, data: [] },
color: { size: 4, data: [] },
}, options.buffers )
const camera = object.assign( {
fov: 60,
near: 1,
far: 10000,
aspect: 1,
z: 100,
perspective: true,
}, options.camera )
const canvas = document.createelement( 'canvas' )
const gl = canvas.getcontext( 'webgl', { antialias: options.antialias } )
if ( ! gl ) return false
this.count = 0
this.gl = gl
this.canvas = canvas
this.camera = camera
this.holder = holder
this.onupdate = options.onupdate
this.onresize = options.onresize
this.data = {}
holder.appendchild( canvas )
this.createprogram( options.vertex, options.fragment )
this.createbuffers( buffers )
this.createuniforms( uniforms )
this.updatebuffers()
this.updateuniforms()
this.createtexture( options.texture )
gl.enable( gl.blend )
gl.enable( gl.cull_face )
gl.blendfunc( gl.src_alpha, gl.one )
gl[ options.depthtest ? 'enable' : 'disable' ]( gl.depth_test )
if ( options.autosize )
window.addeventlistener( 'resize', e => this.resize( e ), false )
if ( options.mousemove )
window.addeventlistener( 'mousemove', e => this.mousemove( e ), false )
this.resize()
this.update = this.update.bind( this )
this.time = { start: performance.now(), old: performance.now() }
this.update()
}
mousemove( e ) {
let x = e.pagex / this.width * 2 - 1
let y = e.pagey / this.height * 2 - 1
this.uniforms.mousemove = [ x, y ]
}
resize( e ) {
const holder = this.holder
const canvas = this.canvas
const gl = this.gl
const width = this.width = holder.offsetwidth
const height = this.height = holder.offsetheight
const aspect = this.aspect = width / height
const dpi = this.dpi = devicepixelratio
canvas.width = width * dpi
canvas.height = height * dpi
canvas.style.width = width + 'px'
canvas.style.height = height + 'px'
gl.viewport( 0, 0, width * dpi, height * dpi )
gl.clearcolor( 0, 0, 0, 0 )
this.uniforms.resolution = [ width, height ]
this.uniforms.projection = this.setprojection( aspect )
this.onresize( width, height, dpi )
}
setprojection( aspect ) {
const camera = this.camera
if ( camera.perspective ) {
camera.aspect = aspect
const fovrad = camera.fov * ( math.pi / 180 )
const f = math.tan( math.pi * 0.5 - 0.5 * fovrad )
const rangeinv = 1.0 / ( camera.near - camera.far )
const matrix = [
f / camera.aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (camera.near + camera.far) * rangeinv, -1,
0, 0, camera.near * camera.far * rangeinv * 2, 0
]
matrix[ 14 ] += camera.z
matrix[ 15 ] += camera.z
return matrix
} else {
return [
2 / this.width, 0, 0, 0,
0, -2 / this.height, 0, 0,
0, 0, 1, 0,
-1, 1, 0, 1,
]
}
}
createshader( type, source ) {
const gl = this.gl
const shader = gl.createshader( type )
gl.shadersource( shader, source )
gl.compileshader( shader )
if ( gl.getshaderparameter (shader, gl.compile_status ) ) {
return shader
} else {
console.log( gl.getshaderinfolog( shader ) )
gl.deleteshader( shader )
}
}
createprogram( vertex, fragment ) {
const gl = this.gl
const vertexshader = this.createshader( gl.vertex_shader, vertex )
const fragmentshader = this.createshader( gl.fragment_shader, fragment )
const program = gl.createprogram()
gl.attachshader( program, vertexshader )
gl.attachshader( program, fragmentshader )
gl.linkprogram( program )
if ( gl.getprogramparameter( program, gl.link_status ) ) {
gl.useprogram( program )
this.program = program
} else {
console.log( gl.getprograminfolog( program ) )
gl.deleteprogram( program )
}
}
createuniforms( data ) {
const gl = this.gl
const uniforms = this.data.uniforms = data
const values = this.uniforms = {}
object.keys( uniforms ).foreach( name => {
const uniform = uniforms[ name ]
uniform.location = gl.getuniformlocation( this.program, 'u_' + name )
object.defineproperty( values, name, {
set: value => {
uniforms[ name ].value = value
this.setuniform( name, value )
},
get: () => uniforms[ name ].value
} )
} )
}
setuniform( name, value ) {
const gl = this.gl
const uniform = this.data.uniforms[ name ]
uniform.value = value
switch ( uniform.type ) {
case 'int': {
gl.uniform1i( uniform.location, value )
break
}
case 'float': {
gl.uniform1f( uniform.location, value )
break
}
case 'vec2': {
gl.uniform2f( uniform.location, ...value )
break
}
case 'vec3': {
gl.uniform3f( uniform.location, ...value )
break
}
case 'vec4': {
gl.uniform4f( uniform.location, ...value )
break
}
case 'mat2': {
gl.uniformmatrix2fv( uniform.location, false, value )
break
}
case 'mat3': {
gl.uniformmatrix3fv( uniform.location, false, value )
break
}
case 'mat4': {
gl.uniformmatrix4fv( uniform.location, false, value )
break
}
}
// ivec2 : uniform2i,
// ivec3 : uniform3i,
// ivec4 : uniform4i,
// sampler2d : uniform1i,
// samplercube : uniform1i,
// bool : uniform1i,
// bvec2 : uniform2i,
// bvec3 : uniform3i,
// bvec4 : uniform4i,
}
updateuniforms() {
const gl = this.gl
const uniforms = this.data.uniforms
object.keys( uniforms ).foreach( name => {
const uniform = uniforms[ name ]
this.uniforms[ name ] = uniform.value
} )
}
createbuffers( data ) {
const gl = this.gl
const buffers = this.data.buffers = data
const values = this.buffers = {}
object.keys( buffers ).foreach( name => {
const buffer = buffers[ name ]
buffer.buffer = this.createbuffer( 'a_' + name, buffer.size )
object.defineproperty( values, name, {
set: data => {
buffers[ name ].data = data
this.setbuffer( name, data )
if ( name == 'position' )
this.count = buffers.position.data.length / 3
},
get: () => buffers[ name ].data
} )
} )
}
createbuffer( name, size ) {
const gl = this.gl
const program = this.program
const index = gl.getattriblocation( program, name )
const buffer = gl.createbuffer()
gl.bindbuffer( gl.array_buffer, buffer )
gl.enablevertexattribarray( index )
gl.vertexattribpointer( index, size, gl.float, false, 0, 0 )
return buffer
}
setbuffer( name, data ) {
const gl = this.gl
const buffers = this.data.buffers
if ( name == null && ! gl.bindbuffer( gl.array_buffer, null ) ) return
gl.bindbuffer( gl.array_buffer, buffers[ name ].buffer )
gl.bufferdata( gl.array_buffer, new float32array( data ), gl.static_draw )
}
updatebuffers() {
const gl = this.gl
const buffers = this.buffers
object.keys( buffers ).foreach( name =>
buffers[ name ] = buffer.data
)
this.setbuffer( null )
}
createtexture( src ) {
const gl = this.gl
const texture = gl.createtexture()
gl.bindtexture( gl.texture_2d, texture )
gl.teximage2d( gl.texture_2d, 0, gl.rgba, 1, 1, 0, gl.rgba, gl.unsigned_byte, new uint8array( [ 0, 0, 0, 0 ] ) )
this.texture = texture
if ( src ) {
this.uniforms.hastexture = 1
this.loadtexture( src )
}
}
loadtexture( src ) {
const gl = this.gl
const texture = this.texture
const textureimage = new image()
textureimage.onload = () => {
gl.bindtexture( gl.texture_2d, texture )
gl.teximage2d( gl.texture_2d, 0, gl.rgba, gl.rgba, gl.unsigned_byte, textureimage )
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.generatemipmap( gl.texture_2d )
}
textureimage.src = src
}
update() {
const gl = this.gl
const now = performance.now()
const elapsed = ( now - this.time.start ) / 5000
const delta = now - this.time.old
this.time.old = now
this.uniforms.time = elapsed
if ( this.count > 0 ) {
gl.clear( gl.colorbufferbit )
gl.drawarrays( gl.points, 0, this.count )
}
this.onupdate( delta )
requestanimationframe( this.update )
}
}
const pointsize = .8
const waves = new shaderprogram( document.queryselector( '.waves' ), {
texture: 'data:image/png;base64,ivborw0kggoaaaansuheugaaacaaaaagcamaaabepirgaaaab1bmveuaaad///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8v0wlraaaajhrstlmac/gogvdhmwcexrvjwzrm29trqqskenrxvklansiue8mrkgpv+hofaaabceleqvq4y4vt13ldmawlruhteo+r9f/fwmfo6dlapekveecrxoulwsegps9nuldwia2y+alqunbaweg775zv+sa4/ffrmxt8u2fzfcvwjr/yrh4/h9sarclskdpmwkzb8vseehb3m0shkhvcynzexeaq9xl4opeiex2qcgnwgbj6gmyjw9t1k0fk9yzunpxeagsfjtyjwzxabnozggoryz0ypk2hzqsyx1y8dgsro2ewoiyh2qwoek1y9orqv0a8tibm1a8emhwynrmy7cz4t1cmyrkhsuvp3grxyhoclbxnoc3ijv//zrj/kxxuhpub+6jjzzhrpg6gojnqaomzp4ndr48olxn/h27srq08s0zjaaaaaelftksuqmcc',
uniforms: {
size: { type: 'float', value: pointsize },
field: { type: 'vec3', value: [ 0, 0, 0 ] },
speed: { type: 'float', value: 5 },
},
vertex: `
#define m_pi 3.1415926535897932384626433832795
precision highp float;
attribute vec4 a_position;
attribute vec4 a_color;
uniform float u_time;
uniform float u_size;
uniform float u_speed;
uniform vec3 u_field;
uniform mat4 u_projection;
varying vec4 v_color;
void main() {
vec3 pos = a_position.xyz;
pos.y += (
cos(pos.x / u_field.x * m_pi * 8.0 + u_time * u_speed) +
sin(pos.z / u_field.z * m_pi * 8.0 + u_time * u_speed)
) * u_field.y;
gl_position = u_projection * vec4( pos.xyz, a_position.w );
gl_pointsize = ( u_size / gl_position.w ) * 100.0;
v_color = a_color;
}`,
fragment: `
precision highp float;
uniform sampler2d u_texture;
varying vec4 v_color;
void main() {
gl_fragcolor = v_color * texture2d(u_texture, gl_pointcoord);
}`,
onresize( w, h, dpi ) {
const position = [], color = []
const width = 80 * ( w / h )
const depth = 400
const height = 3
const distance = 2
for ( let x = 0; x < width; x += distance ) {
for ( let z = 0; z < depth; z+= distance ) {
position.push( - width / 2 + x, -30, -depth / 2 + z )
//color.push( 0, 1 - ( x / width ) * 1, 0.5 + x / width * 0.5, z / depth )
color.push( 0.0, 0.0 , 0.0 , z / depth )
}
}
this.uniforms.field = [ width, height, depth ]
this.buffers.position = position
this.buffers.color = color
this.uniforms.size = ( h / 600) * pointsize * dpi
},
})
//粒子 end
/**
* particleground
*
* @author jonathan nicol - @mrjnicol
* @version 1.0.1
* @description creates a canvas based particle system background
*
* inspired by:
* http://requestlab.fr/
* http://disruptivebydesign.com/
*
* @license the mit license (mit)
*
* copyright (c) 2014 jonathan nicol - @mrjnicol
*
* permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "software"), to deal
* in the software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the software, and to permit persons to whom the software is
* furnished to do so, subject to the following conditions:
*
* the above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the software.
*
* the software is provided "as is", without warranty of any kind, express or
* implied, including but not limited to the warranties of merchantability,
* fitness for a particular purpose and noninfringement. in no event shall the
* authors or copyright holders be liable for any claim, damages or other
* liability, whether in an action of contract, tort or otherwise, arising from,
* out of or in connection with the software or the use or other dealings in
* the software.
*/
!function(a){function b(b,d){function e(){if(w){$canvas=a(''),v.prepend($canvas),p=$canvas[0],q=p.getcontext("2d"),f();for(var b=math.round(p.width*p.height/d.density),c=0;b>c;c++){var e=new l;e.setstackpos(c),x.push(e)}a(window).on("resize",function(){h()}),a(document).on("mousemove",function(a){y=a.pagex,z=a.pagey}),b&&!a&&window.addeventlistener("deviceorientation",function(){d=math.min(math.max(-event.beta,-30),30),c=math.min(math.max(-event.gamma,-30),30)},!0),g(),o("oninit")}}function f(){p.width=v.width(),p.height=v.height(),q.fillstyle=d.dotcolor,q.strokestyle=d.linecolor,q.linewidth=d.linewidth}function g(){if(w){s=a(window).width(),t=a(window).height(),q.clearrect(0,0,p.width,p.height);for(var b=0;b=0;i--)(x[i].position.x>v.width()||x[i].position.y>v.height())&&x.splice(i,1);var a=math.round(p.width*p.height/d.density);if(a>x.length)for(;a>x.length;){var b=new l;x.push(b)}else a=0;i--)x[i].setstackpos(i)}function j(){e=!0}function k(){e=!1,g()}function l(){switch(this.stackpos,this.active=!0,this.layer=math.ceil(3*math.random()),this.parallaxoffsetx=0,this.parallaxoffsety=0,this.position={x:math.ceil(math.random()*p.width),y:math.ceil(math.random()*p.height)},this.speed={},d.directionx){case"left":this.speed.x=+(-d.maxspeedx+math.random()*d.maxspeedx-d.minspeedx).tofixed(2);break;case"right":this.speed.x=+(math.random()*d.maxspeedx+d.minspeedx).tofixed(2);break;default:this.speed.x=+(-d.maxspeedx/2+math.random()*d.maxspeedx).tofixed(2),this.speed.x+=this.speed.x>0?d.minspeedx:-d.minspeedx}switch(d.directiony){case"up":this.speed.y=+(-d.maxspeedy+math.random()*d.maxspeedy-d.minspeedy).tofixed(2);break;case"down":this.speed.y=+(math.random()*d.maxspeedy+d.minspeedy).tofixed(2);break;default:this.speed.y=+(-d.maxspeedy/2+math.random()*d.maxspeedy).tofixed(2),this.speed.x+=this.speed.y>0?d.minspeedy:-d.minspeedy}}function m(a,b){return b?void(d[a]=b):d[a]}function n(){v.find(".pg-canvas").remove(),o("ondestroy"),v.removedata("plugin_"+c)}function o(a){void 0!==d[a]&&d[a].call(u)}var p,q,r,s,t,u=b,v=a(b),w=!!document.createelement("canvas").getcontext,x=[],y=0,z=0,a=!navigator.useragent.match(/(iphone|ipod|ipad|android|blackberry|bb10|mobi|tablet|opera mini|nexus 7)/i),b=!!window.deviceorientationevent,c=0,d=0,e=!1;return d=a.extend({},a.fn[c].defaults,d),l.prototype.draw=function(){q.beginpath(),q.arc(this.position.x+this.parallaxoffsetx,this.position.y+this.parallaxoffsety,d.particleradius/2,0,2*math.pi,!0),q.closepath(),q.fill(),q.beginpath();for(var a=x.length-1;a>this.stackpos;a--){var b=x[a],c=this.position.x-b.position.x,e=this.position.y-b.position.y,f=math.sqrt(c*c+e*e).tofixed(2);fv.width()&&(this.position.x=0-this.parallaxoffsetx);break;default:(this.position.x+this.speed.x+this.parallaxoffsetx>v.width()||this.position.x+this.speed.x+this.parallaxoffsetx<0)&&(this.speed.x=-this.speed.x)}switch(d.directiony){case"up":this.position.y+this.speed.y+this.parallaxoffsety<0&&(this.position.y=v.height()-this.parallaxoffsety);break;case"down":this.position.y+this.speed.y+this.parallaxoffsety>v.height()&&(this.position.y=0-this.parallaxoffsety);break;default:(this.position.y+this.speed.y+this.parallaxoffsety>v.height()||this.position.y+this.speed.y+this.parallaxoffsety<0)&&(this.speed.y=-this.speed.y)}this.position.x+=this.speed.x,this.position.y+=this.speed.y},l.prototype.setstackpos=function(a){this.stackpos=a},e(),{option:m,destroy:n,start:k,pause:j}}var c="particleground";a.fn[c]=function(d){if("string"==typeof arguments[0]){var e,f=arguments[0],g=array.prototype.slice.call(arguments,1);return this.each(function(){a.data(this,"plugin_"+c)&&"function"==typeof a.data(this,"plugin_"+c)[f]&&(e=a.data(this,"plugin_"+c)[f].apply(this,g))}),void 0!==e?e:this}return"object"!=typeof d&&d?void 0:this.each(function(){a.data(this,"plugin_"+c)||a.data(this,"plugin_"+c,new b(this,d))})},a.fn[c].defaults={minspeedx:.1,maxspeedx:.7,minspeedy:.1,maxspeedy:.7,directionx:"center",directiony:"center",density:1e4,dotcolor:"#666666",linecolor:"#666666",particleradius:7,linewidth:1,curvedlines:!1,proximity:100,parallax:!0,parallaxmultiplier:5,oninit:function(){},ondestroy:function(){}}}(jquery),/**
* requestanimationframe polyfill by erik möller. fixes from paul irish and tino zijdel
* @see: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* @see: http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
* @license: mit license
*/
function(){for(var a=0,b=["ms","moz","webkit","o"],c=0;c