JSDM

HTML

1
 
1
<canvas id="canvas"></canvas>
!

CSS

x
 
1
html, body {
2
    margin: 0;
3
    padding: 0;
4
    width: 100%;
5
    height: 100%;
6
}
7
8
body {
9
    overflow: hidden;
10
    background-color: #fff;
11
}
!
? ?
? ?
必须是有效的URL
+ 添加另一个资源

JS

453
 
1
var canvas = document.getElementById( "canvas" );
2
var size = {
3
    width: window.innerWidth,
4
    height: window.innerHeight
5
};
6
7
window.requestAnimtionFrame =
8
    window.requestAnimationFrame ||
9
    window.webkitRequestAnimationFrame ||
10
    window.mozRequestAnimationFrame ||
11
    window.oRequestAnimationFrame ||
12
    window.msRequestAnimationFrame ||
13
    function( callback ) {
14
        window.setTimeout( callback, 1000 / 60 );
15
    };
16
17
var options = {
18
    color: "#777",
19
    waveAmplitude: 30,
20
    waveRadius: 100,
21
    waveElasticity: 0.95,
22
    waveStrength: 0.011,
23
    waveMouse: 10,
24
    waveMax: 100,
25
    waveComeUp: function() {},
26
    waveRiseSpeed: 15,
27
};
28
29
var Mouse = ( function() {
30
31
    var exports = {
32
        x: 0,
33
        y: 0,
34
        bind: function( canvas ) {
35
            canvas.addEventListener( "mousemove", onMouseMove );
36
        },
37
        unbind: function( canvas ) {
38
            canvas.removeEventListener( "mousemove", onMouseMove );
39
        }
40
    };
41
42
    function onMouseMove( event ) {
43
        exports.x = event.pageX;
44
        exports.y = event.pageY;
45
    }
46
47
    return exports;
48
49
} )();
50
51
var Stage = {
52
    width: 1,
53
    height: 1,
54
    set: function( values ) {
55
        Stage.width = values.width;
56
        Stage.height = values.height;
57
    }
58
};
59
60
var times = function( amount, closure ) {
61
    for ( var i = 0; i < amount; i++ ) {
62
        closure( i );
63
    }
64
};
65
66
var func = function ( name ) {
67
    return function( obj ) {
68
        return obj[ name ]();
69
    };
70
};
71
72
73
var rand = function( min, max ) {
74
    return min + ( max - min ) * Math.random();
75
};
76
77
var bezier = function( points, context ) {
78
79
    var a, b, x, y;
80
81
    for ( var i = 1, length = points.length - 2; i < length; i++ ) {
82
83
        a = points[ i ];
84
        b = points[ i + 1 ];
85
86
        x = ( a.x + b.x ) * .5
87
        y = ( a.y + b.y ) * .5
88
89
        context.quadraticCurveTo( a.x, a.y, x, y );
90
    }
91
92
    a = points[ i ];
93
    b = points[ i + 1 ];
94
95
    context.quadraticCurveTo( a.x, a.y, b.x, b.y );
96
}
97
98
var distance = function( a, b ) {
99
    var x = b.x - a.x;
100
    var y = b.y - a.y;
101
102
    return Math.sqrt( x * x + y * y );
103
};
104
105
var clamp = function( val, min, max ) {
106
    return val < min ? min : ( val > max ? max : val );
107
}
108
109
var Water = function( context ) {
110
111
    var waves;
112
113
    function init() {
114
        options.waveComeUp = this.start.bind( this );
115
    }
116
117
    this.render = function() {
118
        context.strokeStyle = options.color;
119
        context.lineWidth = 1;
120
        context.beginPath();
121
122
        waves.forEach( func( "render" ) );
123
124
        context.stroke();
125
    };
126
127
    this.setSize = function( width, height ) {
128
129
        createWaves( height );
130
131
        waves.forEach( function( wave ) {
132
            wave.setSize( width, height );
133
        } );
134
135
    };
136
137
    this.start = function() {
138
        waves.forEach( func( "start" ) );
139
    };
140
141
    function createWaves( height ) {
142
143
        waves = [];
144
        var distance = 50;
145
146
        times( height / distance, function( index ) {
147
            waves.push( new Wave( 0, index * distance + 10, context, rand( 0.18, 0.22 ) * index ) );
148
        } );
149
150
    }
151
152
    init.call( this );
153
154
};
155
156
var Wave = function( originalX, originalY, context, offset ) {
157
158
    var anchors;
159
    var width;
160
    var height;
161
    var mouseDirection;
162
    var oldMouse;
163
    var x;
164
    var y;
165
166
    function init() {
167
        x = targetX = originalX;
168
        y = targetY = originalY;
169
170
        anchors = [];
171
        mouseDirection = { x: 0, y: 0 };
172
173
        var anchor;
174
        var current = 0;
175
        var start = - options.waveAmplitude;
176
        var target = options.waveAmplitude;
177
        var delta = offset;
178
        var step = 0.4;
179
180
        times( 20, function() {
181
            anchor = new Anchor( current, 0, start, target, delta );
182
            anchor.setOrigin( current + x, y );
183
184
            anchors.push( anchor );
185
186
            current += 90;
187
            delta += step;
188
189
            if ( delta > 1 ) {
190
                times( Math.floor( delta ), function() {
191
                    delta--;
192
                    start *= -1;
193
                    target *= -1;
194
                } );
195
            }
196
197
        } );
198
    }
199
200
    this.render = function() {
201
202
        update();
203
204
        context.save();
205
        context.translate( x, y );
206
207
        context.moveTo( anchors[ 0 ].x, anchors[ 0 ].y );
208
        bezier( anchors, context );
209
210
        context.restore();
211
    };
212
213
    this.setSize = function( _width, _height ) {
214
        width = _width;
215
        height = _height;
216
217
        var step = _width / ( anchors.length - 1 );
218
219
        anchors.forEach( function( anchor, i ) {
220
            anchor.x = step * i;
221
            anchor.setOrigin( anchor.x, y );
222
        } );
223
    };
224
225
    this.onAmpChange = function() {
226
        anchors.forEach( func( "onAmpChange" ) );
227
    };
228
229
    this.start = function() {
230
        y = height + 300 + originalY * 0.4;
231
    };
232
233
    function update() {
234
        targetY = Math.min( y, Mouse.y + originalY );
235
        y += ( targetY - y ) / options.waveRiseSpeed;
236
237
        updateMouse();
238
239
        anchors.forEach( function( anchor ) {
240
            anchor.update( mouseDirection, y );
241
        } );
242
    }
243
244
    function updateMouse() {
245
        if ( ! oldMouse ) {
246
            oldMouse = { x: Mouse.x, y: Mouse.y };
247
            return;
248
        }
249
250
        mouseDirection.x = Mouse.x - oldMouse.x;
251
        mouseDirection.y = Mouse.y - oldMouse.y;
252
253
        oldMouse = { x: Mouse.x, y: Mouse.y };
254
    }
255
256
    init.call( this );
257
258
};
259
260
var Anchor = function( x, y, start, target, delta ) {
261
262
    var spring;
263
    var motion;
264
    var origin;
265
266
    function init() {
267
        spring = new Spring();
268
        motion = new Motion( start, target, delta );
269
        origin = {};
270
        this.x = x;
271
        this.y = y;
272
    }
273
274
    this.update = function( mouseDirection, currentY ) {
275
        origin.y = currentY;
276
277
        var factor = getMultiplier();
278
        var vector = {
279
            x: mouseDirection.x * factor * options.waveMouse,
280
            y: mouseDirection.y * factor * options.waveMouse
281
        }
282
283
        if ( factor > 0 ) {
284
            spring.shoot( vector );
285
        }
286
287
        spring.update();
288
        motion.update();
289
290
        this.y = motion.get() + spring.y;
291
    };
292
293
    this.onAmpChange = function() {
294
        motion.onAmpChange();
295
    };
296
297
    this.setOrigin = function( x, y ) {
298
        origin.x = x;
299
        origin.y = y;
300
    };
301
302
303
    function getMultiplier() {
304
        var lang = distance( Mouse, origin );
305
        var radius = options.waveRadius;
306
307
        return  lang < radius ? 1 - lang / radius : 0;
308
    }
309
310
    init.call( this );
311
312
};
313
314
var Motion = function( start, target, delta ) {
315
316
    var SPEED = 0.02;
317
    var half;
318
    var upper;
319
    var lower;
320
    var min;
321
    var max;
322
323
    function init() {
324
        this.onAmpChange();
325
    }
326
327
328
    this.setRange = function( a, b ) {
329
        min = a;
330
        max = b;
331
    };
332
333
    this.update = function() {
334
        delta += SPEED;
335
336
        if ( delta > 1 ) {
337
            delta = 0;
338
            start = target;
339
            target = target < half ? rand( upper, max ) : rand( min, lower );
340
        }
341
    };
342
343
    this.get = function() {
344
        var factor = ( Math.cos( ( 1 + delta ) * Math.PI ) + 1 ) / 2;
345
        return start + factor * ( target - start );
346
    };
347
348
    this.onAmpChange = function() {
349
        min = - options.waveAmplitude;
350
        max = options.waveAmplitude;
351
        half = min + ( max - min ) / 2;
352
        upper = min + ( max - min ) * .75;
353
        lower = min + ( max - min ) * .25;
354
    };
355
356
357
    init.call( this );
358
359
};
360
361
var Spring = function() {
362
363
    var px = 0;
364
    var py = 0;
365
    var vx = 0;
366
    var vy = 0;
367
    var targetX = 0;
368
    var targetY = 0;
369
    var timeout;
370
371
    function init() {
372
        this.x = 0;
373
        this.y = 0;
374
    }
375
376
    this.update = function() {
377
        vx = targetX - this.x;
378
        vy = targetY - this.y;
379
        px = px * options.waveElasticity + vx * options.waveStrength;
380
        py = py * options.waveElasticity + vy * options.waveStrength;
381
        this.x += px;
382
        this.y += py;
383
    };
384
385
    this.shoot = function( vector ) {
386
        targetX = clamp( vector.x, -options.waveMax, options.waveMax );
387
        targetY = clamp( vector.y, -options.waveMax, options.waveMax );
388
389
        clearTimeout( timeout );
390
        timeout = setTimeout( cancelOffset, 100 );
391
    };
392
393
    function cancelOffset() {
394
        targetX = 0;
395
        targetY = 0;
396
    }
397
398
    init.call( this );
399
};
400
401
var Canvas = function( canvas, size ) {
402
403
    var context;
404
    var width, height;
405
    var animations;
406
    var alive = true;
407
408
    function init() {
409
410
        context = canvas.getContext( "2d" );
411
412
        setTimeout( function() {
413
            Mouse.bind( canvas );
414
        }, 1000 );
415
416
        Stage.set( size );
417
418
        animation = new Water( context );
419
420
        this.setSize( size.width, size.height );
421
422
        animation.start();
423
424
        requestAnimtionFrame( render );
425
    }
426
427
    function render() {
428
        context.setTransform( 1, 0, 0, 1, 0, 0 );
429
        context.clearRect( 0, 0, width, height );
430
431
        context.save();
432
        animation.render();
433
        context.restore();
434
435
        requestAnimtionFrame( render );
436
    }
437
438
    this.setSize = function( _width, _height ) {
439
440
        canvas.width = Stage.width = width = _width;
441
        canvas.height = Stage.height = height = _height;
442
443
        animation.setSize( _width, _height );
444
    }
445
446
    init.call( this );
447
};
448
449
var app = new Canvas( canvas, size );
450
451
window.addEventListener( "resize", function() {
452
    app.setSize( window.innerWidth, window.innerHeight );
453
}, false );
!
必须是有效的URL
+ 添加另一个资源
Close

文件管理 点击文件查看URL

图片

  1. 暂无文件

CSS

  1. 暂无文件

JavaScript

  1. 暂无文件

其他

  1. 暂无文件
拖动文件到上面的区域或者:
加载中 ..................