QQ登录框背景渐变动画特效

版权:原创 更新时间:1年以上
[该文章底部包含文件资源,可根据自己情况,决定是否下载资源使用,时间>金钱,如有需要,立即查看资源]

以下是 QQ登录框背景渐变动画特效 的示例演示效果:

当前平台(PC电脑)
  • 平台:

部分效果截图:

QQ登录框背景渐变动画特效

HTML代码(index.html):

<!doctype html>
<html>
  <head>
    <meta charset="gb2312"/>
    <title>QQ��¼�򱳾����䶯����Ч</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <style>
    body {
      background: #111118;
      margin: 0;
    }
    .container {
      position: absolute;
      height: 100%;
      width: 100%;
    }
    </style>

  </head>
  <body>

    <div id="container" class="container">
    </div>

    <script src="deploy/fss.js"></script>
    <script>

    var container = document.getElementById('container');
    var renderer = new FSS.CanvasRenderer();
    var scene = new FSS.Scene();
    var light = new FSS.Light('#111122', '#FF0022');
    var geometry = new FSS.Plane(600, 400, 6, 4);
    var material = new FSS.Material('#FFFFFF', '#FFFFFF');
    var mesh = new FSS.Mesh(geometry, material);
    var now, start = Date.now();

    function initialise() {
      scene.add(mesh);
      scene.add(light);
      container.appendChild(renderer.element);
      window.addEventListener('resize', resize);
    }

    function resize() {
      renderer.setSize(container.offsetWidth, container.offsetHeight);
    }

    function animate() {
      now = Date.now() - start;
      light.setPosition(300*Math.sin(now*0.001), 200*Math.cos(now*0.0005), 60);
      renderer.render(scene);
      requestAnimationFrame(animate);
    }

    initialise();
    resize();
    animate();
    </script>
</body>
</html>

JS代码(build.js):

// Dependenciesvar fs = require('fs');
	var uglify = require('uglify-js');
	// Settingsvar FILE_ENCODING = 'utf-8',PROJECT_NAME = 'fss',LICENSE = '../LICENSE.md',SOURCE_DIR = '../source',OUTPUT_DIR = '../deploy',SCRIPTS = [ 'Core.js','Math.js','Vector3.js','Vector4.js','Color.js','Object.js','Light.js','Vertex.js','Triangle.js','Geometry.js','Plane.js','Material.js','Mesh.js','Scene.js','Renderer.js','CanvasRenderer.js','WebGLRenderer.js','SVGRenderer.js' ];
	// Returns a path string from a list of path segmentsfunction getPath(){
	return [].join.call(arguments,'/');
}
// Processes the specified files,creating a concatenated and a concatenated and minified outputfunction process(){
	var joined,license,unminified,minified;
	// Read the license license = fs.readFileSync(LICENSE,FILE_ENCODING);
	// Join the contents of all sources files into a single string joined = SCRIPTS.map(function(file){
	return fs.readFileSync(getPath(SOURCE_DIR,file),FILE_ENCODING);
}
).join('\n');
	// Unminified unminified = license + '\n' + joined;
	// Minified minified = license + uglify.minify(joined,{
	fromString:true}
).code;
	// Write out the concatenated file fs.writeFileSync(getPath(OUTPUT_DIR,PROJECT_NAME + '.js'),unminified,FILE_ENCODING);
	// Write out the minfied file fs.writeFileSync(getPath(OUTPUT_DIR,PROJECT_NAME + '.min.js'),minified,FILE_ENCODING);
	console.log('build complete');
}
// GO!process();
	

JS代码(fss.js):

//============================================================//// Copyright (C) 2013 Matthew Wagerfield//// Twitter:https://twitter.com/mwagerfield//// 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.////============================================================/** * Defines the Flat Surface Shader namespace for all the awesomeness to exist upon. * @author Matthew Wagerfield */
FSS ={
	FRONT:0,BACK:1,DOUBLE:2,SVGNS:'http://www.w3.org/2000/svg'}
;
	/** * @class Array * @author Matthew Wagerfield */
FSS.Array = typeof Float32Array === 'function' ? Float32Array:Array;
	/** * @class Utils * @author Matthew Wagerfield */
FSS.Utils ={
	isNumber:function(value){
	return !isNaN(parseFloat(value)) && isFinite(value);
}
}
;
	/** * Request Animation Frame Polyfill. * @author Paul Irish * @see https://gist.github.com/paulirish/1579671 */
(function(){
	var lastTime = 0;
	var vendors = ['ms','moz','webkit','o'];
	for(var x = 0;
	x < vendors.length && !window.requestAnimationFrame;
	++x){
	window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
	window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame){
	window.requestAnimationFrame = function(callback,element){
	var currentTime = new Date().getTime();
	var timeToCall = Math.max(0,16 - (currentTime - lastTime));
	var id = window.setTimeout(function(){
	callback(currentTime + timeToCall);
}
,timeToCall);
	lastTime = currentTime + timeToCall;
	return id;
}
;
}
if (!window.cancelAnimationFrame){
	window.cancelAnimationFrame = function(id){
	clearTimeout(id);
}
;
}
}
());
	/** * @object Math Augmentation * @author Matthew Wagerfield */
Math.PIM2 = Math.PI*2;
	Math.PID2 = Math.PI/2;
	Math.randomInRange = function(min,max){
	return min + (max - min) * Math.random();
}
;
	Math.clamp = function(value,min,max){
	value = Math.max(value,min);
	value = Math.min(value,max);
	return value;
}
;
	/** * @object Vector3 * @author Matthew Wagerfield */
FSS.Vector3 ={
	create:function(x,y,z){
	var vector = new FSS.Array(3);
	this.set(vector,x,y,z);
	return vector;
}
,clone:function(a){
	var vector = this.create();
	this.copy(vector,a);
	return vector;
}
,set:function(target,x,y,z){
	target[0] = x || 0;
	target[1] = y || 0;
	target[2] = z || 0;
	return this;
}
,setX:function(target,x){
	target[0] = x || 0;
	return this;
}
,setY:function(target,y){
	target[1] = y || 0;
	return this;
}
,setZ:function(target,z){
	target[2] = z || 0;
	return this;
}
,copy:function(target,a){
	target[0] = a[0];
	target[1] = a[1];
	target[2] = a[2];
	return this;
}
,add:function(target,a){
	target[0] += a[0];
	target[1] += a[1];
	target[2] += a[2];
	return this;
}
,addVectors:function(target,a,b){
	target[0] = a[0] + b[0];
	target[1] = a[1] + b[1];
	target[2] = a[2] + b[2];
	return this;
}
,addScalar:function(target,s){
	target[0] += s;
	target[1] += s;
	target[2] += s;
	return this;
}
,subtract:function(target,a){
	target[0] -= a[0];
	target[1] -= a[1];
	target[2] -= a[2];
	return this;
}
,subtractVectors:function(target,a,b){
	target[0] = a[0] - b[0];
	target[1] = a[1] - b[1];
	target[2] = a[2] - b[2];
	return this;
}
,subtractScalar:function(target,s){
	target[0] -= s;
	target[1] -= s;
	target[2] -= s;
	return this;
}
,multiply:function(target,a){
	target[0] *= a[0];
	target[1] *= a[1];
	target[2] *= a[2];
	return this;
}
,multiplyVectors:function(target,a,b){
	target[0] = a[0] * b[0];
	target[1] = a[1] * b[1];
	target[2] = a[2] * b[2];
	return this;
}
,multiplyScalar:function(target,s){
	target[0] *= s;
	target[1] *= s;
	target[2] *= s;
	return this;
}
,divide:function(target,a){
	target[0] /= a[0];
	target[1] /= a[1];
	target[2] /= a[2];
	return this;
}
,divideVectors:function(target,a,b){
	target[0] = a[0] / b[0];
	target[1] = a[1] / b[1];
	target[2] = a[2] / b[2];
	return this;
}
,divideScalar:function(target,s){
	if (s !== 0){
	target[0] /= s;
	target[1] /= s;
	target[2] /= s;
}
else{
	target[0] = 0;
	target[1] = 0;
	target[2] = 0;
}
return this;
}
,cross:function(target,a){
	var x = target[0];
	var y = target[1];
	var z = target[2];
	target[0] = y*a[2] - z*a[1];
	target[1] = z*a[0] - x*a[2];
	target[2] = x*a[1] - y*a[0];
	return this;
}
,crossVectors:function(target,a,b){
	target[0] = a[1]*b[2] - a[2]*b[1];
	target[1] = a[2]*b[0] - a[0]*b[2];
	target[2] = a[0]*b[1] - a[1]*b[0];
	return this;
}
,min:function(target,value){
	if (target[0] < value){
	target[0] = value;
}
if (target[1] < value){
	target[1] = value;
}
if (target[2] < value){
	target[2] = value;
}
return this;
}
,max:function(target,value){
	if (target[0] > value){
	target[0] = value;
}
if (target[1] > value){
	target[1] = value;
}
if (target[2] > value){
	target[2] = value;
}
return this;
}
,clamp:function(target,min,max){
	this.min(target,min);
	this.max(target,max);
	return this;
}
,limit:function(target,min,max){
	var length = this.length(target);
	if (min !== null && length < min){
	this.setLength(target,min);
}
else if (max !== null && length > max){
	this.setLength(target,max);
}
return this;
}
,dot:function(a,b){
	return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}
,normalise:function(target){
	return this.divideScalar(target,this.length(target));
}
,negate:function(target){
	return this.multiplyScalar(target,-1);
}
,distanceSquared:function(a,b){
	var dx = a[0] - b[0];
	var dy = a[1] - b[1];
	var dz = a[2] - b[2];
	return dx*dx + dy*dy + dz*dz;
}
,distance:function(a,b){
	return Math.sqrt(this.distanceSquared(a,b));
}
,lengthSquared:function(a){
	return a[0]*a[0] + a[1]*a[1] + a[2]*a[2];
}
,length:function(a){
	return Math.sqrt(this.lengthSquared(a));
}
,setLength:function(target,l){
	var length = this.length(target);
	if (length !== 0 && l !== length){
	this.multiplyScalar(target,l / length);
}
return this;
}
}
;
	/** * @object Vector4 * @author Matthew Wagerfield */
FSS.Vector4 ={
	create:function(x,y,z,w){
	var vector = new FSS.Array(4);
	this.set(vector,x,y,z);
	return vector;
}
,set:function(target,x,y,z,w){
	target[0] = x || 0;
	target[1] = y || 0;
	target[2] = z || 0;
	target[3] = w || 0;
	return this;
}
,setX:function(target,x){
	target[0] = x || 0;
	return this;
}
,setY:function(target,y){
	target[1] = y || 0;
	return this;
}
,setZ:function(target,z){
	target[2] = z || 0;
	return this;
}
,setW:function(target,w){
	target[3] = w || 0;
	return this;
}
,add:function(target,a){
	target[0] += a[0];
	target[1] += a[1];
	target[2] += a[2];
	target[3] += a[3];
	return this;
}
,multiplyVectors:function(target,a,b){
	target[0] = a[0] * b[0];
	target[1] = a[1] * b[1];
	target[2] = a[2] * b[2];
	target[3] = a[3] * b[3];
	return this;
}
,multiplyScalar:function(target,s){
	target[0] *= s;
	target[1] *= s;
	target[2] *= s;
	target[3] *= s;
	return this;
}
,min:function(target,value){
	if (target[0] < value){
	target[0] = value;
}
if (target[1] < value){
	target[1] = value;
}
if (target[2] < value){
	target[2] = value;
}
if (target[3] < value){
	target[3] = value;
}
return this;
}
,max:function(target,value){
	if (target[0] > value){
	target[0] = value;
}
if (target[1] > value){
	target[1] = value;
}
if (target[2] > value){
	target[2] = value;
}
if (target[3] > value){
	target[3] = value;
}
return this;
}
,clamp:function(target,min,max){
	this.min(target,min);
	this.max(target,max);
	return this;
}
}
;
	/** * @class Color * @author Matthew Wagerfield */
FSS.Color = function(hex,opacity){
	this.rgba = FSS.Vector4.create();
	this.hex = hex || '#000000';
	this.opacity = FSS.Utils.isNumber(opacity) ? opacity:1;
	this.set(this.hex,this.opacity);
}
;
	FSS.Color.prototype ={
	set:function(hex,opacity){
	hex = hex.replace('#','');
	var size = hex.length / 3;
	this.rgba[0] = parseInt(hex.substring(size*0,size*1),16) / 255;
	this.rgba[1] = parseInt(hex.substring(size*1,size*2),16) / 255;
	this.rgba[2] = parseInt(hex.substring(size*2,size*3),16) / 255;
	this.rgba[3] = FSS.Utils.isNumber(opacity) ? opacity:this.rgba[3];
	return this;
}
,hexify:function(channel){
	var hex = Math.ceil(channel*255).toString(16);
	if (hex.length === 1){
	hex = '0' + hex;
}
return hex;
}
,format:function(){
	var r = this.hexify(this.rgba[0]);
	var g = this.hexify(this.rgba[1]);
	var b = this.hexify(this.rgba[2]);
	this.hex = '#' + r + g + b;
	return this.hex;
}
}
;
	/** * @class Object * @author Matthew Wagerfield */
FSS.Object = function(){
	this.position = FSS.Vector3.create();
}
;
	FSS.Object.prototype ={
	setPosition:function(x,y,z){
	FSS.Vector3.set(this.position,x,y,z);
	return this;
}
}
;
	/** * @class Light * @author Matthew Wagerfield */
FSS.Light = function(ambient,diffuse){
	FSS.Object.call(this);
	this.ambient = new FSS.Color(ambient || '#FFFFFF');
	this.diffuse = new FSS.Color(diffuse || '#FFFFFF');
	this.ray = FSS.Vector3.create();
}
;
	FSS.Light.prototype = Object.create(FSS.Object.prototype);
	/** * @class Vertex * @author Matthew Wagerfield */
FSS.Vertex = function(x,y,z){
	this.position = FSS.Vector3.create(x,y,z);
}
;
	FSS.Vertex.prototype ={
	setPosition:function(x,y,z){
	FSS.Vector3.set(this.position,x,y,z);
	return this;
}
}
;
	/** * @class Triangle * @author Matthew Wagerfield */
FSS.Triangle = function(a,b,c){
	this.a = a || new FSS.Vertex();
	this.b = b || new FSS.Vertex();
	this.c = c || new FSS.Vertex();
	this.vertices = [this.a,this.b,this.c];
	this.u = FSS.Vector3.create();
	this.v = FSS.Vector3.create();
	this.centroid = FSS.Vector3.create();
	this.normal = FSS.Vector3.create();
	this.color = new FSS.Color();
	this.polygon = document.createElementNS(FSS.SVGNS,'polygon');
	this.polygon.setAttributeNS(null,'stroke-linejoin','round');
	this.polygon.setAttributeNS(null,'stroke-miterlimit','1');
	this.polygon.setAttributeNS(null,'stroke-width','1');
	this.computeCentroid();
	this.computeNormal();
}
;
	FSS.Triangle.prototype ={
	computeCentroid:function(){
	this.centroid[0] = this.a.position[0] + this.b.position[0] + this.c.position[0];
	this.centroid[1] = this.a.position[1] + this.b.position[1] + this.c.position[1];
	this.centroid[2] = this.a.position[2] + this.b.position[2] + this.c.position[2];
	FSS.Vector3.divideScalar(this.centroid,3);
	return this;
}
,computeNormal:function(){
	FSS.Vector3.subtractVectors(this.u,this.b.position,this.a.position);
	FSS.Vector3.subtractVectors(this.v,this.c.position,this.a.position);
	FSS.Vector3.crossVectors(this.normal,this.u,this.v);
	FSS.Vector3.normalise(this.normal);
	return this;
}
}
;
	/** * @class Geometry * @author Matthew Wagerfield */
FSS.Geometry = function(){
	this.vertices = [];
	this.triangles = [];
	this.dirty = false;
}
;
	FSS.Geometry.prototype ={
	update:function(){
	if (this.dirty){
	var t,triangle;
	for (t = this.triangles.length - 1;
	t >= 0;
	t--){
	triangle = this.triangles[t];
	triangle.computeCentroid();
	triangle.computeNormal();
}
this.dirty = false;
}
return this;
}
}
;
	/** * @class Plane * @author Matthew Wagerfield */
FSS.Plane = function(width,height,segments,slices){
	FSS.Geometry.call(this);
	this.width = width || 100;
	this.height = height || 100;
	this.segments = segments || 4;
	this.slices = slices || 4;
	this.segmentWidth = this.width / this.segments;
	this.sliceHeight = this.height / this.slices;
	// Cache Variables var x,y,v0,v1,v2,v3,vertex,triangle,vertices = [],offsetX = this.width * -0.5,offsetY = this.height * 0.5;
	// Add Vertices for (x = 0;
	x <= this.segments;
	x++){
	vertices.push([]);
	for (y = 0;
	y <= this.slices;
	y++){
	vertex = new FSS.Vertex(offsetX + x*this.segmentWidth,offsetY - y*this.sliceHeight);
	vertices[x].push(vertex);
	this.vertices.push(vertex);
}
}
// Add Triangles for (x = 0;
	x < this.segments;
	x++){
	for (y = 0;
	y < this.slices;
	y++){
	v0 = vertices[x+0][y+0];
	v1 = vertices[x+0][y+1];
	v2 = vertices[x+1][y+0];
	v3 = vertices[x+1][y+1];
	t0 = new FSS.Triangle(v0,v1,v2);
	t1 = new FSS.Triangle(v2,v1,v3);
	this.triangles.push(t0,t1);
}
}
}
;
	FSS.Plane.prototype = Object.create(FSS.Geometry.prototype);
	/** * @class Material * @author Matthew Wagerfield */
FSS.Material = function(ambient,diffuse){
	this.ambient = new FSS.Color(ambient || '#444444');
	this.diffuse = new FSS.Color(diffuse || '#FFFFFF');
	this.slave = new FSS.Color();
}
;
	/** * @class Mesh * @author Matthew Wagerfield */
FSS.Mesh = function(geometry,material){
	FSS.Object.call(this);
	this.geometry = geometry || new FSS.Geometry();
	this.material = material || new FSS.Material();
	this.side = FSS.FRONT;
	this.visible = true;
}
;
	FSS.Mesh.prototype = Object.create(FSS.Object.prototype);
	FSS.Mesh.prototype.update = function(lights,calculate){
	var t,triangle,l,light,illuminance;
	// Update Geometry this.geometry.update();
	// Calculate the triangle colors if (calculate){
	// Iterate through Triangles for (t = this.geometry.triangles.length - 1;
	t >= 0;
	t--){
	triangle = this.geometry.triangles[t];
	// Reset Triangle Color FSS.Vector4.set(triangle.color.rgba);
	// Iterate through Lights for (l = lights.length - 1;
	l >= 0;
	l--){
	light = lights[l];
	// Calculate Illuminance FSS.Vector3.subtractVectors(light.ray,light.position,triangle.centroid);
	FSS.Vector3.normalise(light.ray);
	illuminance = FSS.Vector3.dot(triangle.normal,light.ray);
	if (this.side === FSS.FRONT){
	illuminance = Math.max(illuminance,0);
}
else if (this.side === FSS.BACK){
	illuminance = Math.abs(Math.min(illuminance,0));
}
else if (this.side === FSS.DOUBLE){
	illuminance = Math.max(Math.abs(illuminance),0);
}
// Calculate Ambient Light FSS.Vector4.multiplyVectors(this.material.slave.rgba,this.material.ambient.rgba,light.ambient.rgba);
	FSS.Vector4.add(triangle.color.rgba,this.material.slave.rgba);
	// Calculate Diffuse Light FSS.Vector4.multiplyVectors(this.material.slave.rgba,this.material.diffuse.rgba,light.diffuse.rgba);
	FSS.Vector4.multiplyScalar(this.material.slave.rgba,illuminance);
	FSS.Vector4.add(triangle.color.rgba,this.material.slave.rgba);
}
// Clamp & Format Color FSS.Vector4.clamp(triangle.color.rgba,0,1);
}
}
return this;
}
;
	/** * @class Scene * @author Matthew Wagerfield */
FSS.Scene = function(){
	this.meshes = [];
	this.lights = [];
}
;
	FSS.Scene.prototype ={
	add:function(object){
	if (object instanceof FSS.Mesh && !~this.meshes.indexOf(object)){
	this.meshes.push(object);
}
else if (object instanceof FSS.Light && !~this.lights.indexOf(object)){
	this.lights.push(object);
}
return this;
}
,remove:function(object){
	if (object instanceof FSS.Mesh && ~this.meshes.indexOf(object)){
	this.meshes.splice(this.meshes.indexOf(object),1);
}
else if (object instanceof FSS.Light && ~this.lights.indexOf(object)){
	this.lights.splice(this.lights.indexOf(object),1);
}
return this;
}
}
;
	/** * @class Renderer * @author Matthew Wagerfield */
FSS.Renderer = function(){
	this.width = 0;
	this.height = 0;
	this.halfWidth = 0;
	this.halfHeight = 0;
}
;
	FSS.Renderer.prototype ={
	setSize:function(width,height){
	if (this.width === width && this.height === height) return;
	this.width = width;
	this.height = height;
	this.halfWidth = this.width * 0.5;
	this.halfHeight = this.height * 0.5;
	return this;
}
,clear:function(){
	return this;
}
,render:function(scene){
	return this;
}
}
;
	/** * @class Canvas Renderer * @author Matthew Wagerfield */
FSS.CanvasRenderer = function(){
	FSS.Renderer.call(this);
	this.element = document.createElement('canvas');
	this.element.style.display = 'block';
	this.context = this.element.getContext('2d');
	this.setSize(this.element.width,this.element.height);
}
;
	FSS.CanvasRenderer.prototype = Object.create(FSS.Renderer.prototype);
	FSS.CanvasRenderer.prototype.setSize = function(width,height){
	FSS.Renderer.prototype.setSize.call(this,width,height);
	this.element.width = width;
	this.element.height = height;
	this.context.setTransform(1,0,0,-1,this.halfWidth,this.halfHeight);
	return this;
}
;
	FSS.CanvasRenderer.prototype.clear = function(){
	FSS.Renderer.prototype.clear.call(this);
	this.context.clearRect(-this.halfWidth,-this.halfHeight,this.width,this.height);
	return this;
}
;
	FSS.CanvasRenderer.prototype.render = function(scene){
	FSS.Renderer.prototype.render.call(this,scene);
	var m,mesh,t,triangle,color;
	// Clear Context this.clear();
	// Configure Context this.context.lineJoin = 'round';
	this.context.lineWidth = 1;
	// Update Meshes for (m = scene.meshes.length - 1;
	m >= 0;
	m--){
	mesh = scene.meshes[m];
	if (mesh.visible){
	mesh.update(scene.lights,true);
	// Render Triangles for (t = mesh.geometry.triangles.length - 1;
	t >= 0;
	t--){
	triangle = mesh.geometry.triangles[t];
	color = triangle.color.format();
	this.context.beginPath();
	this.context.moveTo(triangle.a.position[0],triangle.a.position[1]);
	this.context.lineTo(triangle.b.position[0],triangle.b.position[1]);
	this.context.lineTo(triangle.c.position[0],triangle.c.position[1]);
	this.context.closePath();
	this.context.strokeStyle = color;
	this.context.fillStyle = color;
	this.context.stroke();
	this.context.fill();
}
}
}
return this;
}
;
	/** * @class WebGL Renderer * @author Matthew Wagerfield */
FSS.WebGLRenderer = function(){
	FSS.Renderer.call(this);
	this.element = document.createElement('canvas');
	this.element.style.display = 'block';
	// Set initial vertex and light count this.vertices = null;
	this.lights = null;
	// Create parameters object var parameters ={
	preserveDrawingBuffer:false,premultipliedAlpha:true,antialias:true,stencil:true,alpha:true}
;
	// Create and configure the gl context this.gl = this.getContext(this.element,parameters);
	// Set the internal support flag this.unsupported = !this.gl;
	// Setup renderer if (this.unsupported){
	return 'WebGL is not supported by your browser.';
}
else{
	this.gl.clearColor(0.0,0.0,0.0,0.0);
	this.gl.enable(this.gl.DEPTH_TEST);
	this.setSize(this.element.width,this.element.height);
}
}
;
	FSS.WebGLRenderer.prototype = Object.create(FSS.Renderer.prototype);
	FSS.WebGLRenderer.prototype.getContext = function(canvas,parameters){
	var context = false;
	try{
	if (!(context = canvas.getContext('experimental-webgl',parameters))){
	throw 'Error creating WebGL context.';
}
}
catch (error){
	console.error(error);
}
return context;
}
;
	FSS.WebGLRenderer.prototype.setSize = function(width,height){
	FSS.Renderer.prototype.setSize.call(this,width,height);
	if (this.unsupported) return;
	// Set the size of the canvas element this.element.width = width;
	this.element.height = height;
	// Set the size of the gl viewport this.gl.viewport(0,0,width,height);
	return this;
}
;
	FSS.WebGLRenderer.prototype.clear = function(){
	FSS.Renderer.prototype.clear.call(this);
	if (this.unsupported) return;
	this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
	return this;
}
;
	FSS.WebGLRenderer.prototype.render = function(scene){
	FSS.Renderer.prototype.render.call(this,scene);
	if (this.unsupported) return;
	var m,mesh,t,tl,triangle,l,light,attribute,uniform,buffer,data,location,update = false,lights = scene.lights.length,index,v,vl,vetex,vertices = 0;
	// Clear context this.clear();
	// Build the shader program if (this.lights !== lights){
	this.lights = lights;
	if (this.lights > 0){
	this.buildProgram(lights);
}
else{
	return;
}
}
// Update program if (!!this.program){
	// Increment vertex counter for (m = scene.meshes.length - 1;
	m >= 0;
	m--){
	mesh = scene.meshes[m];
	if (mesh.geometry.dirty) update = true;
	mesh.update(scene.lights,false);
	vertices += mesh.geometry.triangles.length*3;
}
// Compare vertex counter if (update || this.vertices !== vertices){
	this.vertices = vertices;
	// Build buffers for (attribute in this.program.attributes){
	buffer = this.program.attributes[attribute];
	buffer.data = new FSS.Array(vertices*buffer.size);
	// Reset vertex index index = 0;
	// Update attribute buffer data for (m = scene.meshes.length - 1;
	m >= 0;
	m--){
	mesh = scene.meshes[m];
	for (t = 0,tl = mesh.geometry.triangles.length;
	t < tl;
	t++){
	triangle = mesh.geometry.triangles[t];
	for (v = 0,vl = triangle.vertices.length;
	v < vl;
	v++){
	vertex = triangle.vertices[v];
	switch (attribute){
	case 'side':this.setBufferData(index,buffer,mesh.side);
	break;
	case 'position':this.setBufferData(index,buffer,vertex.position);
	break;
	case 'centroid':this.setBufferData(index,buffer,triangle.centroid);
	break;
	case 'normal':this.setBufferData(index,buffer,triangle.normal);
	break;
	case 'ambient':this.setBufferData(index,buffer,mesh.material.ambient.rgba);
	break;
	case 'diffuse':this.setBufferData(index,buffer,mesh.material.diffuse.rgba);
	break;
}
index++;
}
}
}
// Upload attribute buffer data this.gl.bindBuffer(this.gl.ARRAY_BUFFER,buffer.buffer);
	this.gl.bufferData(this.gl.ARRAY_BUFFER,buffer.data,this.gl.DYNAMIC_DRAW);
	this.gl.enableVertexAttribArray(buffer.location);
	this.gl.vertexAttribPointer(buffer.location,buffer.size,this.gl.FLOAT,false,0,0);
}
}
// Build uniform buffers this.setBufferData(0,this.program.uniforms.resolution,[this.width,this.height,this.width]);
	for (l = lights-1;
	l >= 0;
	l--){
	light = scene.lights[l];
	this.setBufferData(l,this.program.uniforms.lightPosition,light.position);
	this.setBufferData(l,this.program.uniforms.lightAmbient,light.ambient.rgba);
	this.setBufferData(l,this.program.uniforms.lightDiffuse,light.diffuse.rgba);
}
// Update uniforms for (uniform in this.program.uniforms){
	buffer = this.program.uniforms[uniform];
	location = buffer.location;
	data = buffer.data;
	switch (buffer.structure){
	case '3f':this.gl.uniform3f(location,data[0],data[1],data[2]);
	break;
	case '3fv':this.gl.uniform3fv(location,data);
	break;
	case '4fv':this.gl.uniform4fv(location,data);
	break;
}
}
}
// Draw those lovely triangles this.gl.drawArrays(this.gl.TRIANGLES,0,this.vertices);
	return this;
}
;
	FSS.WebGLRenderer.prototype.setBufferData = function(index,buffer,value){
	if (FSS.Utils.isNumber(value)){
	buffer.data[index*buffer.size] = value;
}
else{
	for (var i = value.length - 1;
	i >= 0;
	i--){
	buffer.data[index*buffer.size+i] = value[i];
}
}
}
;
	/** * Concepts taken from three.js WebGLRenderer * @see https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js */
FSS.WebGLRenderer.prototype.buildProgram = function(lights){
	if (this.unsupported) return;
	// Create shader source var vs = FSS.WebGLRenderer.VS(lights);
	var fs = FSS.WebGLRenderer.FS(lights);
	// Derive the shader fingerprint var code = vs + fs;
	// Check if the program has already been compiled if (!!this.program && this.program.code === code) return;
	// Create the program and shaders var program = this.gl.createProgram();
	var vertexShader = this.buildShader(this.gl.VERTEX_SHADER,vs);
	var fragmentShader = this.buildShader(this.gl.FRAGMENT_SHADER,fs);
	// Attach an link the shader this.gl.attachShader(program,vertexShader);
	this.gl.attachShader(program,fragmentShader);
	this.gl.linkProgram(program);
	// Add error handling if (!this.gl.getProgramParameter(program,this.gl.LINK_STATUS)){
	var error = this.gl.getError();
	var status = this.gl.getProgramParameter(program,this.gl.VALIDATE_STATUS);
	console.error('Could not initialise shader.\nVALIDATE_STATUS:'+status+'\nERROR:'+error);
	return null;
}
// Delete the shader this.gl.deleteShader(fragmentShader);
	this.gl.deleteShader(vertexShader);
	// Set the program code program.code = code;
	// Add the program attributes program.attributes ={
	side:this.buildBuffer(program,'attribute','aSide',1,'f' ),position:this.buildBuffer(program,'attribute','aPosition',3,'v3'),centroid:this.buildBuffer(program,'attribute','aCentroid',3,'v3'),normal:this.buildBuffer(program,'attribute','aNormal',3,'v3'),ambient:this.buildBuffer(program,'attribute','aAmbient',4,'v4'),diffuse:this.buildBuffer(program,'attribute','aDiffuse',4,'v4')}
;
	// Add the program uniforms program.uniforms ={
	resolution:this.buildBuffer(program,'uniform','uResolution',3,'3f',1 ),lightPosition:this.buildBuffer(program,'uniform','uLightPosition',3,'3fv',lights),lightAmbient:this.buildBuffer(program,'uniform','uLightAmbient',4,'4fv',lights),lightDiffuse:this.buildBuffer(program,'uniform','uLightDiffuse',4,'4fv',lights)}
;
	// Set the renderer program this.program = program;
	// Enable program this.gl.useProgram(this.program);
	// Return the program return program;
}
;
	FSS.WebGLRenderer.prototype.buildShader = function(type,source){
	if (this.unsupported) return;
	// Create and compile shader var shader = this.gl.createShader(type);
	this.gl.shaderSource(shader,source);
	this.gl.compileShader(shader);
	// Add error handling if (!this.gl.getShaderParameter(shader,this.gl.COMPILE_STATUS)){
	console.error(this.gl.getShaderInfoLog(shader));
	return null;
}
// Return the shader return shader;
}
;
	FSS.WebGLRenderer.prototype.buildBuffer = function(program,type,identifier,size,structure,count){
	var buffer ={
	buffer:this.gl.createBuffer(),size:size,structure:structure,data:null}
;
	// Set the location switch (type){
	case 'attribute':buffer.location = this.gl.getAttribLocation(program,identifier);
	break;
	case 'uniform':buffer.location = this.gl.getUniformLocation(program,identifier);
	break;
}
// Create the buffer if count is provided if (!!count){
	buffer.data = new FSS.Array(count*size);
}
// Return the buffer return buffer;
}
;
	FSS.WebGLRenderer.VS = function(lights){
	var shader = [ // Precision 'precision mediump float;
	',// Lights '#define LIGHTS ' + lights,// Attributes 'attribute float aSide;
	','attribute vec3 aPosition;
	','attribute vec3 aCentroid;
	','attribute vec3 aNormal;
	','attribute vec4 aAmbient;
	','attribute vec4 aDiffuse;
	',// Uniforms 'uniform vec3 uResolution;
	','uniform vec3 uLightPosition[LIGHTS];
	','uniform vec4 uLightAmbient[LIGHTS];
	','uniform vec4 uLightDiffuse[LIGHTS];
	',// Varyings 'varying vec4 vColor;
	',// Main 'void main(){
	',// Create color 'vColor = vec4(0.0);
	',// Calculate the vertex position 'vec3 position = aPosition / uResolution * 2.0;
	',// Iterate through lights 'for (int i = 0;
	i < LIGHTS;
	i++){
	','vec3 lightPosition = uLightPosition[i];
	','vec4 lightAmbient = uLightAmbient[i];
	','vec4 lightDiffuse = uLightDiffuse[i];
	',// Calculate illuminance 'vec3 ray = normalize(lightPosition - aCentroid);
	','float illuminance = dot(aNormal,ray);
	','if (aSide == 0.0){
	','illuminance = max(illuminance,0.0);
	','}
else if (aSide == 1.0){
	','illuminance = abs(min(illuminance,0.0));
	','}
else if (aSide == 2.0){
	','illuminance = max(abs(illuminance),0.0);
	','}
',// Calculate ambient light 'vColor += aAmbient * lightAmbient;
	',// Calculate diffuse light 'vColor += aDiffuse * lightDiffuse * illuminance;
	','}
',// Clamp color 'vColor = clamp(vColor,0.0,1.0);
	',// Set gl_Position 'gl_Position = vec4(position,1.0);
	','}
' // Return the shader ].join('\n');
	return shader;
}
;
	FSS.WebGLRenderer.FS = function(lights){
	var shader = [ // Precision 'precision mediump float;
	',// Varyings 'varying vec4 vColor;
	',// Main 'void main(){
	',// Set gl_FragColor 'gl_FragColor = vColor;
	','}
' // Return the shader ].join('\n');
	return shader;
}
;
	/** * @class SVG Renderer * @author Matthew Wagerfield */
FSS.SVGRenderer = function(){
	FSS.Renderer.call(this);
	this.element = document.createElementNS(FSS.SVGNS,'svg');
	this.element.setAttribute('xmlns',FSS.SVGNS);
	this.element.setAttribute('version','1.1');
	this.element.style.display = 'block';
	this.setSize(300,150);
}
;
	FSS.SVGRenderer.prototype = Object.create(FSS.Renderer.prototype);
	FSS.SVGRenderer.prototype.setSize = function(width,height){
	FSS.Renderer.prototype.setSize.call(this,width,height);
	this.element.setAttribute('width',width);
	this.element.setAttribute('height',height);
	return this;
}
;
	FSS.SVGRenderer.prototype.clear = function(){
	FSS.Renderer.prototype.clear.call(this);
	for (var i = this.element.childNodes.length - 1;
	i >= 0;
	i--){
	this.element.removeChild(this.element.childNodes[i]);
}
return this;
}
;
	FSS.SVGRenderer.prototype.render = function(scene){
	FSS.Renderer.prototype.render.call(this,scene);
	var m,mesh,t,triangle,points,style;
	// Update Meshes for (m = scene.meshes.length - 1;
	m >= 0;
	m--){
	mesh = scene.meshes[m];
	if (mesh.visible){
	mesh.update(scene.lights,true);
	// Render Triangles for (t = mesh.geometry.triangles.length - 1;
	t >= 0;
	t--){
	triangle = mesh.geometry.triangles[t];
	if (triangle.polygon.parentNode !== this.element){
	this.element.appendChild(triangle.polygon);
}
points = this.formatPoint(triangle.a)+' ';
	points += this.formatPoint(triangle.b)+' ';
	points += this.formatPoint(triangle.c);
	style = this.formatStyle(triangle.color.format());
	triangle.polygon.setAttributeNS(null,'points',points);
	triangle.polygon.setAttributeNS(null,'style',style);
}
}
}
return this;
}
;
	FSS.SVGRenderer.prototype.formatPoint = function(vertex){
	return (this.halfWidth+vertex.position[0])+','+(this.halfHeight-vertex.position[1]);
}
;
	FSS.SVGRenderer.prototype.formatStyle = function(color){
	var style = 'fill:'+color+';
	';
	style += 'stroke:'+color+';
	';
	return style;
}
;
	
附件:下载该文件资源,减少时间成本(增值服务)
留言
该资源可下载
File Source
.rar
29.39 KB
html5特效
最新结算
HTM5 Canvas实现3D飞机飞行动画特效代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
HTM5 Canvas实现3D飞机飞行动画特效代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery图像缩放工具插件Zoomer特效代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery图像缩放工具插件Zoomer特效代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
Labelauty–jQuery单选框_复选框美化插件特效代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
Labelauty–jQuery单选框_复选框美化插件特效代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery网页版打砖块小游戏源码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery网页版打砖块小游戏源码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
jquery虚拟键盘中文打字效果js代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
jquery虚拟键盘中文打字效果js代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
我们力求给您提供有用的文章,再此基础上,会附加营收资源,不做任何广告,让平台可以更好发展 若您发现您的权利被侵害,或使用了您的版权,请发邮件联系 sunlifel@foxmail.com ggbig觉得 : 不提供源码的文章不是好文章
合作伙伴
联系我们
  • QQ:21499807
  • 邮箱:sunlifel@foxmail.com
  • QQ扫一扫加QQ
    QQ扫一扫
Copyright 2023-2024 ggbig.com·皖ICP备2023004211号-1
打赏文章