HTML
<header class="info"> <hgroup class="about"> <h1>Muscular Hydrostats</h1> <h2>Tentacle simulation using inverse kinematics</h2> <h3>Click creature to control</h3> </hgroup> <nav class="more"> <a href="https://github.com/soulwire/Muscular-Hydrostats/zipball/master" target="_blank">Download</a> <a href="https://github.com/soulwire/Muscular-Hydrostats" target="_blank">View on Github</a> </nav></header> <div id="container"></div>
CSS
html, body { background: #f2f2f2; background: -moz-radial-gradient(center, ellipse cover, #ffffff 0%, #ffffff 26%, #f5f5f5 59%, #f5f5f5 77%, #cecece 100%); background: -webkit-gradient(radial, center center, 0, center center, 100%, color-stop(0%,#ffffff), color-stop(26%,#ffffff), color-stop(59%,#f5f5f5), color-stop(77%,#f5f5f5), color-stop(100%,#cecece)); background: -webkit-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); background: -o-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); background: -ms-radial-gradient(center, ellipse cover, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); background: radial-gradient(ellipse at center, #ffffff 0%,#ffffff 26%,#f5f5f5 59%,#f5f5f5 77%,#cecece 100%); overflow: hidden; padding: 0; margin: 0; height: 100%; } body:before { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDRCNjE4NDcxMDgzMTFFMkFGQkM4MzE4NzI4RjhBMkQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDRCNjE4NDgxMDgzMTFFMkFGQkM4MzE4NzI4RjhBMkQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpENEI2MTg0NTEwODMxMUUyQUZCQzgzMTg3MjhGOEEyRCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpENEI2MTg0NjEwODMxMUUyQUZCQzgzMTg3MjhGOEEyRCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp/mixwAABMrSURBVHjaNNrnrptV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); pointer-events: none; position: absolute; content: ''; height: 100%; width: 100%; left: 0; top: 0; } html.dark, body.dark { background: #283442; background: -moz-radial-gradient(center, ellipse cover, #283442 0%, #122335 40%, #000d19 100%); background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,#283442), color-stop(40%,#122335), color-stop(100%,#000d19)); background: -webkit-radial-gradient(center, ellipse cover, #283442 0%,#122335 40%,#000d19 100%); background: -o-radial-gradient(center, ellipse cover, #283442 0%,#122335 40%,#000d19 100%); background: -ms-radial-gradient(center, ellipse cover, #283442 0%,#122335 40%,#000d19 100%); background: radial-gradient(ellipse at center, #283442 0%,#122335 40%,#000d19 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#283442', endColorstr='#000d19',GradientType=1 ); } #container { cursor: pointer; } /* Info */ @-webkit-keyframes show-info { 0% { -webkit-transform: rotateY(120deg); } 100% { -webkit-transform: rotateY(0deg); } } @-moz-keyframes show-info { 0% { -moz-transform: rotateY(120deg); } 100% { -moz-transform: rotateY(0deg); } } @-ms-keyframes show-info { 0% { -ms-transform: rotateY(120deg); } 100% { -ms-transform: rotateY(0deg); } } @-o-keyframes show-info { 0% { -o-transform: rotateY(120deg); } 100% { -o-transform: rotateY(0deg); } } @keyframes show-info { 0% { transform: rotateY(120deg); } 100% { transform: rotateY(0deg); } } .info { -webkit-transition: all 180ms ease-out; -moz-transition: all 180ms ease-out; -ms-transition: all 180ms ease-out; -o-transition: all 180ms ease-out; transition: all 180ms ease-out; -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; -o-transform-style: preserve-3d; transform-style: preserve-3d; -webkit-transform: perspective(800); -moz-transform: perspective(800); -ms-transform: perspective(800); -o-transform: perspective(800); transform: perspective(800); font-family: 'Quantico', sans-serif; position: absolute; font-size: 12px; opacity: 0.85; color: #fff; width: 240px; left: 0px; top: 20px; } .info:hover { box-shadow: 0 0 0 4px rgba(0,0,0,0.1); opacity: 1.0; } .info h1, .info h2, .info h3 { line-height: 1; margin: 5px 0; } .info .about, .info .more { -webkit-transform-origin: 0% 50%; -moz-transform-origin: 0% 50%; -ms-transform-origin: 0% 50%; -o-transform-origin: 0% 50%; transform-origin: 0% 50%; -webkit-transform: rotateY(120deg); -moz-transform: rotateY(120deg); -ms-transform: rotateY(120deg); -o-transform: rotateY(120deg); transform: rotateY(120deg); margin-bottom: 1px; background: rgba(0,0,0,0.95); padding: 12px 15px 12px 20px; } .info .about { -webkit-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 600ms 1 normal forwards; -moz-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 600ms 1 normal forwards; -ms-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 600ms 1 normal forwards; -o-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 600ms 1 normal forwards; animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 600ms 1 normal forwards; padding-bottom: 15px; } .info .about h1 { letter-spacing: -1px; font-weight: 300; font-size: 19px; opacity: 0.95; } .info .about h2 { font-weight: 300; font-size: 13px; opacity: 0.8; } .info .about h3 { text-transform: uppercase; margin-top: 10px; font-size: 11px; } .info .about h3:after { margin-left: 4px; font-size: 14px; content: '\203A'; } .info .more { -webkit-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 500ms 1 normal forwards; -moz-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 500ms 1 normal forwards; -ms-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 500ms 1 normal forwards; -o-animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 500ms 1 normal forwards; animation: show-info 500ms cubic-bezier(0.230, 1.000, 0.320, 1.000) 500ms 1 normal forwards; padding: 5px 15px 10px 20px; } .info .more a { -webkit-transition: all 200ms ease-out; -moz-transition: all 200ms ease-out; -ms-transition: all 200ms ease-out; -o-transition: all 200ms ease-out; transition: all 200ms ease-out; border-bottom: 1px dotted rgba(255,255,255,0.4); text-transform: uppercase; text-decoration: none; margin-right: 10px; font-size: 10px; opacity: 0.6; color: #fff; } .info .more a:hover { opacity: 0.99; }
Java script
/** * Copyright (C) 2012 by Justin Windle * * 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() { var settings = { interactive: false, darkTheme: true, headRadius: 60, thickness: 18, tentacles: 40, friction: 0.02, gravity: 0.5, colour: { h:0, s:0, v:0.1 }, length: 70, pulse: true, wind: -0.5 }; var utils = { curveThroughPoints: function( points, ctx ) { var i, n, a, b, x, y; for ( i = 1, n = points.length - 2; i < n; i++ ) { a = points[i]; b = points[i + 1]; x = ( a.x + b.x ) * 0.5; y = ( a.y + b.y ) * 0.5; ctx.quadraticCurveTo( a.x, a.y, x, y ); } a = points[i]; b = points[i + 1]; ctx.quadraticCurveTo( a.x, a.y, b.x, b.y ); } }; var Node = function( x, y ) { this.x = this.ox = x || 0.0; this.y = this.oy = y || 0.0; this.vx = 0.0; this.vy = 0.0; }; var Tentacle = function( options ) { this.length = options.length || 10; this.radius = options.radius || 10; this.spacing = options.spacing || 20; this.friction = options.friction || 0.8; this.shade = random( 0.85, 1.1 ); this.nodes = []; this.outer = []; this.inner = []; this.theta = []; for ( var i = 0; i < this.length; i++ ) { this.nodes.push( new Node() ); } }; Tentacle.prototype = { move: function( x, y, instant ) { this.nodes[0].x = x; this.nodes[0].y = y; if ( instant ) { var i, node; for ( i = 1; i < this.length; i++ ) { node = this.nodes[i]; node.x = x; node.y = y; } } }, update: function() { var i, n, s, c, dx, dy, da, px, py, node, prev = this.nodes[0]; var radius = this.radius * settings.thickness; var step = radius / this.length; for ( i = 1, j = 0; i < this.length; i++, j++ ) { node = this.nodes[i]; node.x += node.vx; node.y += node.vy; dx = prev.x - node.x; dy = prev.y - node.y; da = Math.atan2( dy, dx ); px = node.x + cos( da ) * this.spacing * settings.length; py = node.y + sin( da ) * this.spacing * settings.length; node.x = prev.x - ( px - node.x ); node.y = prev.y - ( py - node.y ); node.vx = node.x - node.ox; node.vy = node.y - node.oy; node.vx *= this.friction * (1 - settings.friction); node.vy *= this.friction * (1 - settings.friction); node.vx += settings.wind; node.vy += settings.gravity; node.ox = node.x; node.oy = node.y; s = sin( da + HALF_PI ); c = cos( da + HALF_PI ); this.outer[j] = { x: prev.x + c * radius, y: prev.y + s * radius }; this.inner[j] = { x: prev.x - c * radius, y: prev.y - s * radius }; this.theta[j] = da; radius -= step; prev = node; } }, draw: function( ctx ) { var h, s, v, e; s = this.outer[0]; e = this.inner[0]; ctx.beginPath(); ctx.moveTo( s.x, s.y ); utils.curveThroughPoints( this.outer, ctx ); utils.curveThroughPoints( this.inner.reverse(), ctx ); ctx.lineTo( e.x, e.y ); ctx.closePath(); h = settings.colour.h * this.shade; s = settings.colour.s * 100 * this.shade; v = settings.colour.v * 100 * this.shade; ctx.fillStyle = 'hsl(' + h + ',' + s + '%,' + v + '%)'; ctx.fill(); if ( settings.thickness > 2 ) { v += settings.darkTheme ? -10 : 10; ctx.strokeStyle = 'hsl(' + h + ',' + s + '%,' + v + '%)'; ctx.lineWidth = 1; ctx.stroke(); } } }; var demo = true; var ease = 0.1; var modified = false; var radius = settings.headRadius; var tentacles = []; var center = { x:0, y:0 }; var sketch = Sketch.create({ container: document.getElementById( 'container' ), setup: function() { center.x = this.width / 2; center.y = this.height / 2; var tentacle; for ( var i = 0; i < 100; i++ ) { tentacle = new Tentacle({ length: random( 10, 20 ), radius: random( 0.05, 1.0 ), spacing: random( 0.2, 1.0 ), friction: random( 0.7, 0.88 ) }); tentacle.move( center.x, center.y, true ); tentacles.push( tentacle ); } }, update: function() { var t, cx, cy, pulse, touch; t = this.millis * 0.001; if ( settings.pulse ) { pulse = pow( sin( t * PI ), 18 ); radius = settings.headRadius * 0.5 + settings.headRadius * 0.5 * pulse; } if ( settings.interactive ) { ease += ( 0.7 - ease ) * 0.05; touch = this.touches[0] || this.mouse; center.x += ( touch.x - center.x ) * ease; center.y += ( touch.y - center.y ) * ease; } else { t = this.millis; cx = this.width * 0.5; cy = this.height * 0.5; center.x = cx + sin( t * 0.002 ) * cos( t * 0.00005 ) * cx * 0.5; center.y = cy + sin( t * 0.003 ) * tan( sin( t * 0.0003 ) * 1.15 ) * cy * 0.4; } var px, py, theta, tentacle; var step = TWO_PI / settings.tentacles; for ( var i = 0, n = settings.tentacles; i < n; i++ ) { tentacle = tentacles[i]; theta = i * step; px = cos( theta ) * radius; py = sin( theta ) * radius; tentacle.move( center.x + px, center.y + py ); tentacle.update(); } }, draw: function() { var h = settings.colour.h * 0.95; var s = settings.colour.s * 100 * 0.95; var v = settings.colour.v * 100 * 0.95; var w = v + ( settings.darkTheme ? -10 : 10 ); this.beginPath(); this.arc( center.x, center.y, radius + settings.thickness, 0, TWO_PI ); this.lineWidth = settings.headRadius * 0.3; this.globalAlpha = 0.2; this.strokeStyle = 'hsl(' + h + ',' + s + '%,' + w + '%)'; this.stroke(); this.globalAlpha = 1.0; for ( var i = 0, n = settings.tentacles; i < n; i++ ) { tentacles[i].draw( this ); } this.beginPath(); this.arc( center.x, center.y, radius + settings.thickness, 0, TWO_PI ); this.fillStyle = 'hsl(' + h + ',' + s + '%,' + v + '%)'; this.fill(); }, mousedown: function() { if ( demo ) { demo = false; settings.interactive = true; interactiveGUI.updateDisplay(); if ( !modified ) { settings.length = 60; settings.gravity = 0.1; settings.wind = 0.0; } } }, save: function() { window.open( this.canvas.toDataURL(), 'tentacles', "top=20,left=20,width=" + this.width + ",height=" + this.height ); } }); function onSettingsChanged() { modified = true; } function onThemeChanged( dark ) { settings.colour.h = 0; settings.colour.s = 0; settings.colour.v = dark ? 0.8 : 0.1; document.body.className = dark ? 'dark' : ''; colourGUI.updateDisplay(); } var gui = new dat.GUI(); gui.add( settings, 'headRadius' ).min( 0.0 ).max( 100.0 ).onChange( onSettingsChanged ); gui.add( settings, 'tentacles' ).min( 1 ).max( 100 ).onChange( onSettingsChanged ); gui.add( settings, 'thickness' ).min( 1.0 ).max( 40.0 ).onChange( onSettingsChanged ); gui.add( settings, 'length' ).min( 10.0 ).max( 100.0 ).onChange( onSettingsChanged ); gui.add( settings, 'gravity' ).min( -3.0 ).max( 3.0 ).onChange( onSettingsChanged ); gui.add( settings, 'wind' ).min( -3.0 ).max( 3.0 ).onChange( onSettingsChanged ); gui.add( settings, 'friction' ).min( 0.0 ).max( 1.0 ).onChange( onSettingsChanged ); var colourGUI = gui.addColor( settings, 'colour' ); gui.add( settings, 'darkTheme' ).onChange( onThemeChanged ); gui.add( settings, 'pulse' ); var interactiveGUI = gui.add( settings, 'interactive' ); gui.add( sketch, 'autoclear' ); gui.add( sketch, 'save' ); gui.close(); onThemeChanged( true ); });
دموی آنلاین
تا بارگذاری کامل کمی صبر کنید
See the Pen Muscular Hydrostats by Justin Windle (@soulwire) on CodePen