Muscular Hydrostats
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;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://rawgithub.com/soulwire/sketch.js/v1.0/js/sketch.min.js"></script>
<script src="https://dat-gui.googlecode.com/git/build/dat.gui.min.js"></script>
<script src="https://dat-gui.googlecode.com/git/build/dat.color.min.js"></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 );
});
Tentacle simulation using inverse kinematics
A Pen by HARUN PEHLİVAN on CodePen.
<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://gist.github.com/harunpehlivan/41bd915e63e8f70220c04d331f9646b3" target="_blank">Download</a>
<a href="https://github.com/harunpehlivan/Muscular-Hydrostats" target="_blank">View on Github</a>
</nav></header>
<div id="container"></div>