<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Html5实现的超强鼠标跟随效果 - 分享JavaScript-sharejs.com</title> <meta name="Copyright" content="JavaScript分享网 http://www.sharejs.com/" /> <meta name="description" content="Html5实现的超强鼠标跟随效果,JavaScript分享网" /> <meta content="JavaScript,分享,JavaScript代码,Ajax" name="keywords" /> <style type="text/css"> body { font-family: Monospace; background-color: #222222; margin: 0px; overflow: hidden; } </style> <script type="text/javascript"> var g; var canvas; var width = window.innerWidth ; var height = window.innerHeight ; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; var mouseX = 0; var mouseY = 0; var pmouseX = 0; var pmouseY = 0; var mousePressed = false; var drawRate = 6; var frameCount = 0; var PI = Math.PI; var TWO_PI = 2*Math.PI; var HALF_PI = Math.PI*0.5; function init(){ canvas = document.getElementById('canvas'); canvas.width = width; canvas.height = height; g = canvas.getContext('2d'); g.setTransform(1, 0, 0, 1, 0,0); document.addEventListener('mousemove', onDocumentMouseMove, false); document.addEventListener('mousedown', onDocumentMouseDown, false); document.addEventListener('mouseup', onDocumentMouseUp, false); document.addEventListener('keydown', onDocumentKeyDown, false); setup(); drawInternal(); } function windowResize(){ // width = window.innerWidth ; // height = window.innerHeight ; // canvas.width = width; // canvas.height = height; g.setTransform(1, 0, 0, 1, 0,0); } function onDocumentMouseMove(event) { mouseX = event.clientX - canvas.offsetLeft; mouseY = event.clientY - canvas.offsetTop; } function onDocumentMouseDown(event) { mousePressed = true; mousePressedEvent(); } function onDocumentMouseUp(event) { mousePressed = false; } function onDocumentKeyDown(event){ //setup(); } function drawInternal(){ draw(); setTimeout('drawInternal()', drawRate); pmouseX = mouseX; pmouseY = mouseY; frameCount++; } function clear(){ g.clearRect(0,0,width,height); } function line(x1, y1, x2, y2){ g.beginPath(); g.moveTo(x1,y1); g.lineTo(x2,y2); g.closePath(); g.stroke(); } function fillStrokeCircle(x,y,radius){ if(radius<=0) radius = 0; g.beginPath(); g.arc(x, y, radius, 0, TWO_PI, true); g.closePath(); g.fill(); g.stroke(); } function fillCircle(x, y, radius){ if(radius<=0) radius = 0; g.beginPath(); g.arc(x, y, radius, 0, TWO_PI, true); g.closePath(); g.fill(); } function strokeCircle(x, y, radius){ if(radius<=0) radius = 0; g.beginPath(); g.arc(x,y, radius, 0, TWO_PI, true); g.stroke(); } function dist(ax, ay, bx, by) { var dx = bx - ax; dy = by - ay; return Math.sqrt(dx * dx + dy * dy + dz * dz); } var currentRandom = Math.random; // Pseudo-random generator function Marsaglia(i1, i2) { // from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c var z=i1 || 362436069, w= i2 || 521288629; var nextInt = function() { z=(36969*(z&65535)+(z>>>16)) & 0xFFFFFFFF; w=(18000*(w&65535)+(w>>>16)) & 0xFFFFFFFF; return (((z&0xFFFF)<<16) | (w&0xFFFF)) & 0xFFFFFFFF; }; this.nextDouble = function() { var i = nextInt() / 4294967296; return i < 0 ? 1 + i : i; }; this.nextInt = nextInt; } Marsaglia.createRandomized = function() { var now = new Date(); return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF); }; // Noise functions and helpers function PerlinNoise(seed) { var rnd = seed !== undefined ? new Marsaglia(seed) : Marsaglia.createRandomized(); var i, j; // http://www.noisemachine.com/talk1/17b.html // http://mrl.nyu.edu/~perlin/noise/ // generate permutation var p = new Array(512); for(i=0;i<256;++i) { p[i] = i; } for(i=0;i<256;++i) { var t = p[j = rnd.nextInt() & 0xFF]; p[j] = p[i]; p[i] = t; } // copy to avoid taking mod in p[0]; for(i=0;i<256;++i) { p[i + 256] = p[i]; } function grad3d(i,x,y,z) { var h = i & 15; // convert into 12 gradient directions var u = h<8 ? x : y, v = h<4 ? y : h===12||h===14 ? x : z; return ((h&1) === 0 ? u : -u) + ((h&2) === 0 ? v : -v); } function grad2d(i,x,y) { var v = (i & 1) === 0 ? x : y; return (i&2) === 0 ? -v : v; } function grad1d(i,x) { return (i&1) === 0 ? -x : x; } function lerp(t,a,b) { return a + t * (b - a); } this.noise3d = function(x, y, z) { var X = Math.floor(x)&255, Y = Math.floor(y)&255, Z = Math.floor(z)&255; x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z); var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y, fz = (3-2*z)*z*z; var p0 = p[X]+Y, p00 = p[p0] + Z, p01 = p[p0 + 1] + Z, p1 = p[X + 1] + Y, p10 = p[p1] + Z, p11 = p[p1 + 1] + Z; return lerp(fz, lerp(fy, lerp(fx, grad3d(p[p00], x, y, z), grad3d(p[p10], x-1, y, z)), lerp(fx, grad3d(p[p01], x, y-1, z), grad3d(p[p11], x-1, y-1,z))), lerp(fy, lerp(fx, grad3d(p[p00 + 1], x, y, z-1), grad3d(p[p10 + 1], x-1, y, z-1)), lerp(fx, grad3d(p[p01 + 1], x, y-1, z-1), grad3d(p[p11 + 1], x-1, y-1,z-1)))); }; this.noise2d = function(x, y) { var X = Math.floor(x)&255, Y = Math.floor(y)&255; x -= Math.floor(x); y -= Math.floor(y); var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y; var p0 = p[X]+Y, p1 = p[X + 1] + Y; return lerp(fy, lerp(fx, grad2d(p[p0], x, y), grad2d(p[p1], x-1, y)), lerp(fx, grad2d(p[p0 + 1], x, y-1), grad2d(p[p1 + 1], x-1, y-1))); }; this.noise1d = function(x) { var X = Math.floor(x)&255; x -= Math.floor(x); var fx = (3-2*x)*x*x; return lerp(fx, grad1d(p[X], x), grad1d(p[X+1], x-1)); }; } // these are lifted from Processing.js // processing defaults var noiseProfile = { generator: undefined, octaves: 4, fallout: 0.5, seed: undefined}; function noise(x, y, z) { if(noiseProfile.generator === undefined) { // caching noiseProfile.generator = new PerlinNoise(noiseProfile.seed); } var generator = noiseProfile.generator; var effect = 1, k = 1, sum = 0; for(var i=0; i<noiseProfile.octaves; ++i) { effect *= noiseProfile.fallout; switch (arguments.length) { case 1: sum += effect * (1 + generator.noise1d(k*x))/2; break; case 2: sum += effect * (1 + generator.noise2d(k*x, k*y))/2; break; case 3: sum += effect * (1 + generator.noise3d(k*x, k*y, k*z))/2; break; } k *= 2; } return sum; }; function Worm(x,y){ this.x = x; this.y = y; this.lx = x; this.ly = y; this.heading = Math.sin(frameCount*0.083) * PI;; this.rotation = Math.random() * (PI / (Math.random() * 70)); this.rate = 0; this.maxLength = 15 + (noise(frameCount * 0.0025, frameCount*0.1) * 15); this.detail = 2; this.thickness = 3; this.thicknessTarget = 5 + Math.random() * 10; var cIndex = parseInt( Math.random() * colors.length ); this.c = colors[cIndex]; this.life = 30 + Math.random() * 120; this.segments = new Array(); this.ooo = true; this.counter = noise(frameCount * 0.1, frameCount*.1); this.update = function(){ this.life--; if(this.life > 0){ this.thickness += (this.thicknessTarget-this.thickness) * 0.1; this.thickness += 0.1; if(this.thickness > this.thicknessTarget) this.thickness = this.thicknessTarget; this.heading += this.rotation; this.rate = Math.cos( this.counter / 200.0) * (10 + noise(frameCount*0.05) * 10); this.rotation = Math.sin(this.counter/this.rate) * (this.segments.length+1) * 0.010; this.counter++; var speedMod = (this.segments.length * this.segments.length * this.segments.length) * 0.0015 * this.thickness / this.thicknessTarget; var totalSpeed = (this.detail + speedMod); var nx = Math.cos(this.heading) * totalSpeed; var ny = Math.sin(this.heading) * totalSpeed; this.walk(nx,ny); } else{ if(this.segments.length > 1){ this.segments.pop(); } else{ this.thickness*=0.95; this.thickness-=0.2; if(this.thickness<0.1) this.ooo = true; return; } } this.ooo = true; for(var i=0; i<this.segments.length; i++){ var segment = this.segments[i]; if(segment.ooo() == false){ this.ooo = false; break; } } } this.walk = function(nx,ny){ this.lx = this.x; this.ly = this.y; this.x += nx; this.y += ny; var newSegment = new Segment(this.lx,this.ly,this.x,this.y,this.thickness); this.segments.unshift(newSegment); if(this.segments.length > 1) this.segments[this.segments.length-1].smoothAgainst(this.segments[this.segments.length-2]); if(this.segments.length >= this.maxLength){ this.segments.pop(); } } } function Segment(x1,y1,x2,y2,thickness){ this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; this.thickness = thickness; var angle = Math.atan2(y2-y1,x2-x1); this.lAngle = angle - HALF_PI; var lDeltaX = Math.cos(this.lAngle) * thickness; var lDeltaY = Math.sin(this.lAngle) * thickness; this.leftX1 = x1 + lDeltaX; this.leftY1 = y1 + lDeltaY; this.leftX2 = x2 + lDeltaX; this.leftY2 = y2 + lDeltaY; this.rAngle = angle + HALF_PI; var rDeltaX = Math.cos(this.rAngle) * thickness; var rDeltaY = Math.sin(this.rAngle) * thickness; this.rightX1 = x1 + rDeltaX; this.rightY1 = y1 + rDeltaY; this.rightX2 = x2 + rDeltaX; this.rightY2 = y2 + rDeltaY; this.smoothAgainst = function(last){ this.leftX1 = last.leftX2 = (last.leftX2 + this.leftX1) * 0.5; this.leftY1 = last.leftY2 = (last.leftY2 + this.leftY1) * 0.5; this.rightX1 = last.rightX2 = (last.rightX2 + this.rightX1) * 0.5; this.rightY1 = last.rightY2 = (last.rightY2 + this.rightY1) * 0.5; } this.ooo = function(){ if(this.x1 < 0 || this.y1 < 0 || this.x1 > width || this.y1>height || this.x2 < 0 || this.y2 < 0 || this.x2 > width || this.y2>height) return true; else return false; } } var worms; var colors = []; colors[0] = '#2cd9fe'; colors[1] = '#2cfecf'; colors[2] = '#373fdf'; colors[3] = '#88fe1f'; colors[4] = '#48d6ff'; colors[5] = '#b3fcff'; colors[6] = '#f76cad'; colors[7] = '#505083'; colors[8] = '#113a7e'; colors[9] = '#014050'; colors[10] = '#ccf3ef'; colors[11] = '#009437'; colors[12] = '#8fb300'; function setup(){ worms = new Array(); } function draw(){ clear(); for(var w=0; w<worms.length; w++){ var worm = worms[w]; worm.update(); g.fillStyle = worm.c; g.lineWidth = 2; g.strokeStyle = '#ffffff'; if(worm.segments.length>1){ g.beginPath(); g.moveTo(worm.segments[0].leftX1, worm.segments[0].leftY1); for(var i=0; i<worm.segments.length; i++){ var segment = worm.segments[i]; g.lineTo(segment.leftX1,segment.leftY1); } g.lineTo(worm.segments[worm.segments.length-1].rightX1, worm.segments[worm.segments.length-1].rightY1); for(var i=worm.segments.length-1; i>=0; i--){ var segment = worm.segments[i]; g.lineTo(segment.rightX1,segment.rightY1); } g.closePath(); // g.stroke(); g.fill(); g.stroke(); } g.strokeStyle = '#ffffff'; if(worm.segments.length>=1){ var x = worm.segments[0].x1; var y = worm.segments[0].y1; var thickness = worm.segments[0].thickness; if(worm.thickness<thickness) thickness = worm.thickness; if(thickness<=0) thickness = 0.000001; g.beginPath(); g.arc(x, y, thickness, worm.segments[0].lAngle, worm.segments[0].rAngle, false); g.closePath(); //g.fill(); g.stroke(); var xEnd = worm.segments[worm.segments.length-1].x1; var yEnd = worm.segments[worm.segments.length-1].y1; thickness = worm.segments[worm.segments.length-1].thickness; if(worm.thickness<thickness) thickness = worm.thickness; if(thickness<=0) thickness = 0.000001; g.beginPath(); g.arc(xEnd, yEnd, thickness, worm.segments[worm.segments.length-1].lAngle, worm.segments[worm.segments.length-1].rAngle, true); g.closePath(); //g.fill(); g.stroke(); thickness = worm.thickness-0.6; if(worm.thickness<thickness) thickness = worm.thickness; fillCircle(worm.segments[0].x1,worm.segments[0].y1,thickness); thickness = worm.segments[worm.segments.length-1].thickness-0.6; if(worm.thickness<thickness) thickness = worm.thickness; fillCircle(worm.segments[worm.segments.length-1].x1,worm.segments[worm.segments.length-1].y1,thickness); if(worm.life>0){ g.fillStyle = "#FFFFFF"; fillCircle(worm.segments[0].x1,worm.segments[0].y1,thickness * 0.72); } } } for(var w=0; w<worms.length; w++){ var worm = worms[w]; if(worm.ooo){ worms.splice(w,1); w--; } } if(frameCount %2 ==0 && mousePressed && worms.length < 50){ var direction = Math.atan2(pmouseY-mouseY, pmouseX-mouseX) + PI; var newWorm = new Worm(mouseX,mouseY); worms.push( newWorm ); if(mouseX!=pmouseX && mouseY!=pmouseY) newWorm.heading = direction; } } function mousePressedEvent(){ } </script> <style> body { font-family: 'Lobster', serif; font-size: 12px; color: #FFFFFF; } </style> </head> <body onload="init()" onresize="windowResize()"> <div style="position:relative;top:250px;z-index:1;-moz-user-select: none;-khtml-user-select: none;user-select: none;"> <center>请用鼠标在狂点,然后疯狂的晃动!</center> </div> <div style="z-index:4; position:absolute; top:0; left:0"> <canvas id="canvas"></canvas> </div> <br><br> <div align="center">EVENT对象的法宝欣赏 -- 鼠标悬浮事件篇</div> </body> </html>