How To Create Spider Animations In Web Using CSS And HTML

In this post, I will show you how to use spider animations using HTML and CSS languages.

1. Hanging Spider




This is the Style part of the spider Animations (CSS). This is the actual part of the animations.

/*body{
  background: #131416;
}

.box-canvas{
  position: relative;
  margin: auto;
  display: block;
  margin-top: 8%;
  margin-bottom: 8%;
  width: 350px;
  height:600px;
}

.inner {
  margin: 100px;
  position: absolute;
  height: 100px;
  width: 150px;
}

.circle {
  position: absolute;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  box-shadow: 4px 0 0 white;
}

.circle:nth-child(1) {
  bottom: 0;
  transform: rotate(-45deg);
}

.circle:nth-child(2) {
  bottom: -25px;
  left: 50px;
  transform: rotate(-90deg);
}

.circle:nth-child(3) {
  bottom: 0;
  left: 100px;
  transform: rotate(-135deg);
}

.circle:nth-child(4) {
  top: -8px;
  transform: rotate(45deg);
}

.circle:nth-child(5) {
  top: -33px;
  left: 50px;
  transform: rotate(90deg);
}

.circle:nth-child(6) {
  top: -8px;
  left: 100px;
  transform: rotate(135deg);
}

.circle::before {
  content: '';
  position: absolute;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  box-shadow: 4px 0 0 white;
  left: -100px;
  top: 50%;
  transform: translateY(-50%);
}

.circle:nth-child(1)::before {
  top: calc(50% - 20px);
}

.circle:nth-child(3)::before {
  top: calc(50% + 20px);
}

.circle:nth-child(4)::before {
  top: calc(50% + 20px);
}

.circle:nth-child(6)::before {
  top: calc(50% - 20px);
}

.line {
  position: absolute;
  width: 340px;
  height: 3px;
  background: white;
 
}

.line:nth-child(2) {
  transform: rotate(59deg);
  transform-origin: top left;
  left: 90px;
}

.line:nth-child(3) {
  transform: rotate(-59deg);
  transform-origin: top right;
  left: -80px;
}

.line:nth-child(4) {
 top: 145px;
}

.spider {
  --spider-color: #40434F;

  position: absolute;
  width: 75px;
  height: 175px;
  left: 50%;
  transform: translateX(-50%);
  transform-origin: center top;
  top: 148px;
  animation: swing 1s infinite ease-in-out;
  animation-direction: alternate-reverse;
}

@keyframes swing {
  0% {
    transform: translateX(-50%) rotate(25deg);
  }
  
  100% {
    transform: translateX(-50%) rotate(-25deg);
  }
}

.spider::before {
  content: '';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 1px;
  height: 100px;
  background: white;
}

.body {
  position: absolute;
  width: 30px;
  height: 40px;
  border-radius: 50% 50% 40% 40%;
  background: var(--spider-color);
  left: 50%;
  top: 100px;
  transform: translateX(-50%);
}

.body::before {
  content: '';
  position: absolute;
  width: 5px;
  height: 5px;
  background: black;
  border-radius: 50%;
  border: 3px solid white;
  bottom: 6px;
  left: 3px;
}


.body::after {
  content: '';
  position: absolute;
  width: 5px;
  height: 5px;
  background: black;
  border-radius: 50%;
  border: 3px solid white;
  bottom: 6px;
  right: 3px;
}

.leg {
  position: absolute;
 
  top: 10px;
  width: 30px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 -3px 0 var(--spider-color);
}

.leg.left {
   left: -25px;
}

.leg.right {
  right: -25px;
}

.leg::before {
  content: '';
  position: absolute;
  top: 10px;
  width: 30px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 -3px 0 var(--spider-color);
}


.leg::after {
  content: '';
  position: absolute;
  top: 20px;
  width: 20px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 -3px 0 var(--spider-color);
}

.leg.left::after {
  left: 8px;
}

.leg.right::after {
  right: 8px;
}

*/

This is the body section of the spider Animations. You will integrate the CSS part with this in a html document.




2. Moving Spider Animations




body { background-color: #7c7c7c; font-family: "Muli", sans-serif; margin: 0; overflow: hidden; padding: 0; }
.bg { background-image: url('https://www.archerycircuit.com/wp-content/uploads/2016/12/grunge-background-14635619239LT-darken.jpg'); background-repeat: no-repeat; background-size: cover; background-position: center; height: 100vh; left: 0; position: absolute; top: 0; width: 100%; opacity: 0.5; }

/*/////////////////////// general ////*/
// $h:   300px;
$h2:  4px;
// $w:   300px;
$w2:  30px;
$w3:  10px;
$color-black: #000;
$color-shadow: rgba(45,45,45,0.5);

/*/////////////////////// spider ////*/
.container {
  animation: spider-anima 12s ease-out;
  animation-fill-mode: forwards;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  @keyframes spider-anima {
    0%  { top: -100px; }
    50% { top: 50%; }
  }
  .eye {
    background-color: #fff;
    height: 1px;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
  }
  .eye-right {
    right: 6px;
  }
  .eye-left {
    left: 6px;
  }
} 
.spider-web {
  animation: spider-web-anima 6s ease-out;
  animation-fill-mode: forwards;
  background-color: $color-black;
  border-radius: $h2;
  height: 0;
  left: 50%;
  position: absolute;
  transform: translateX(-50%);
  width: 2px;
  @keyframes spider-web-anima {
    0%    { height: 0; top: -100px; }
    100%  { height: 50vh; top: 0;}
  }
}
.spider-body {
  background-color: $color-black;
  border-radius: 50%;
  height: 20px;
  left: 50%;  
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 20px;
  &:before {
    content:"";
    background-color: $color-black;
    border-radius: 50%;
    height: 15px;
    left: 2.5px;
    position: absolute;
    top: -5px;  
    width: 15px;
    z-index: -99;
  }  
}
.right {
  transform: rotateY(180deg);
}
.arm-container {
  .arm {
    background-color: $color-black;
    border-radius: $h2;
    height: $h2;
    position: absolute;
    transform-origin: center left;
    width: $w2;
  }
  .A {
    animation: A-anima 3s infinite ease-in-out;
    transform: rotate(75deg);
    @keyframes A-anima {
      0% {transform: rotate(75deg)}
      50% {transform: rotate(-70deg)}
    }
  }  
  .A:nth-child(2) { animation-delay: -0.2s; }
  .A:nth-child(3) { animation-delay: -0.5s; }
  .A:nth-child(4) { animation-delay: -0.4s; }
  .B {
    animation: B-anima 3s infinite ease-in-out;
    left: calc(100% - 2px);
    transform: rotate(10deg);
    @keyframes B-anima {
      0% {transform: rotate(10deg)}
      50% {transform: rotate(120deg)}
      80% {transform: rotate(20deg)}
    }
  }
  .C {
    animation: C-anima 3s infinite ease-in-out;
    left: calc(100% - 2px);
    transform: rotate(10deg);
    @keyframes C-anima {
      0% {transform: rotate(10deg)}
      50% {transform: rotate(90deg)}
      80% {transform: rotate(10deg)}
    }
  }  
}
/*/////////////////////// shadow ////*/
.shadow {
  left: calc(50% + 10px);
  background-color: $color-shadow;
}
.shadow {
  .arm { background-color: $color-shadow; }
}
.shadow-body {
  background-color: $color-shadow;
  &:before {
   background-color: $color-shadow;
  }
  .eye {
    display: none;
  }
}

/*/////////////////////// credit ////*/
#link {
  bottom: 20px;
  color: #fff;
  opacity: 0.6;
  display: flex;
  align-items: center;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
}
#link p {margin: 0; margin-left: 5px;}
#link:hover {opacity: 1;}

Html Part...




3. Web Spider




body
  background-color #FFEDCC
  width 100%
  height 100%
  padding 0
  margin 0
svg
  position absolute
.web
  stroke-dasharray 5540px
  stroke-dashoffset 5540px
  animation web 45s linear forwards
.spider
  height 25px
  border-radius 50%
  width 30px
  background-color black
  offset-path path('M0,-5.68434189e-14 L400,121.306344 L0,-5.68434189e-14 L400,285.26053 L0,-5.68434189e-14 L227.648438,393.011063 L0,-5.68434189e-14 C1.47046727e-13,17.8535169 2.25196019e-13,25.2141586 2.34447878e-13,22.0819253 C-2.77555756e-15,14.1807654 8.41705907,14.1807654 11.640625,19.7157991 C8.28763081,14.1807654 15.0848911,10.5067251 19.8417969,14.1807654 C14.945707,10.8607743 23.4522008,7.0949205 28.0325521,8.50884303 C23.6102464,7.06995139 28.0325521,5.49661259e-14 31.5846354,9.29745535e-14 C38.4281568,5.49661259e-14 48.5195313,1.29789891e-13 54.4309896,5.49661259e-14 C46.5294557,4.8813185 46.5294557,8.50884303 48.5195313,14.1807654 C41.2105393,16.9519563 36.6946615,21.3136859 36.6946615,26.7802753 C28.0325521,23.9497513 22.1319025,23.9497513 18.8763021,33.1155318 C11.640625,30.7950863 3.78385417,30.7950863 2.34447878e-13,38.0384047 C2.2057009e-13,43.821629 2.2057009e-13,59.215202 2.34447878e-13,64.1860499 C7.4343148,56.7320168 25.1874502,54.4555577 34.4010417,59.215202 C36.6946615,48.5065074 53.7838542,41.5162712 61.3177083,43.821629 C61.3177083,33.9969921 68.2590957,23.9497513 79.1119792,23.9497513 C73.6378482,16.671534 77.3216758,4.8813185 83.8352865,-2.03689637e-14 C90.7457934,1.24335767e-13 112.134766,1.29108126e-13 119.268229,-2.03689637e-14 C108.727867,4.8813185 105.728516,27.8357249 112.134766,33.9969921 C97.8988189,35.8004323 85.2695313,40.5574112 85.2695313,60.9512567 C71.4511719,64.1860499 55.4628906,70.0888918 49.6686198,85.5867304 C31.5846354,79.6449067 7.1953125,86.916597 3.71057352e-13,97.3367633 C5.22238502e-13,107.998724 2.2057009e-13,129.283495 4.88498131e-13,136.360254 C8.22909541,116.886012 63.0292969,112.004315 71.4511719,123.825351 C71.4511719,97.3367633 109.494031,83.7641694 132.746094,94.1614591 C119.268229,76.5474568 143.167493,47.3233558 166.335286,50.4428164 C149.11599,33.9969921 156.222187,8.50884303 180.297145,9.97922086e-14 C205.828125,8.61568983e-14 227.648438,-2.03689637e-14 242.993758,1.05587216e-13 C219.701873,14.1807654 212.533298,45.331624 233.265175,70.6457839 C198.588806,79.5347866 194.428319,119.622371 199.141641,141.995972 C166.335286,139.080349 115.655857,167.385074 112.134766,196.505531 C83.8352865,174.387949 11.0260417,192.607919 0,213.056775 C5.6673416e-13,235.770982 0,276.619163 1.47885176e-13,296.257687 C19.8417969,264.374056 138.786022,256.312929 156.189667,270.093903 C151.31562,231.430198 250.553612,178.478312 270.46507,192.09809 C253.214038,169.143156 275.925719,90.5672912 298.183531,90.5672912 C273.481594,64.1860499 287.900813,4.8813185 314.979288,-5.68434189e-14 C331.131155,1.28767243e-13 392.408609,9.22225724e-14 400,-5.68434189e-14 C366.203125,11.0387592 367.959025,104.10567 400,121.306344 C357.488994,136.360254 375.213512,258.948717 400,285.26053 C351.686185,275.946918 227.648438,374.936648 227.648438,393.011063 C185.794269,373.603023 15.6760986,362.422132 0,400')
  offset-distance 0%
  animation crawl 45s linear forwards
.eye
  background-color white
  height 6px
  width 6px
  border-radius 100%
  position absolute
  top 40%
  animation blink 5s linear infinite
.eye-1
  float left
  left 15%
.eye-2
  left 60%
.leg
  border-top 1px solid black 
  position relative
  height 25%
.leg-left
  left -50%
  border-left 1px solid black
  animation legs-left 1s linear infinite
.leg-right
  left 50%
  top -100%
  border-right 1px solid black
  animation legs-right 1s linear infinite
.leg-1
  transform rotate(45deg)
.leg-2
  transform rotate(25deg)
.leg-3
  transform rotate(5deg)
.leg-4
  transform rotate(-25deg)
.leg-5
  transform rotate(-45deg)
.leg-6
  transform rotate(-25deg)
.leg-7
  transform rotate(5deg)
.leg-8
  transform rotate(25deg)
@keyframes crawl
  to {
    offset-distance: 100%;
  }
    
@keyframes web
  to {
    stroke-dashoffset: 0;
  }
  
@keyframes legs-left
  to {
    left -40%
  }
@keyframes legs-right
  to {
    left 40%
  }
@keyframes blink
    90% {
      height 6px
    }
    95% {
      height 1px
    }
    100% {
      height 6px
    }


Html...





4. Halloween Animation in Pure CSS


@import "compass";

html {
	height: 100%;
	width: 100%; 
	overflow: hidden;
	scroll: none;
}

body {
	background-color: #2F5363;
	@include filter-gradient(#2F5363, #1B2628, horizontal);
	@include background-image(radial-gradient(center, ellipse cover, #2F5363 0%,#1B2628 80%));
	overflow: hidden;
}

[class*="spider"] {
	position: absolute;
	height: 40px;
	width: 50px;
	@include border-radius(50%);
	margin: 40px 0 0 0;
	background: #110D04;
	
	*, &:before, &:after, :after, :before {
		position: absolute;
		content: "";
	}
	
	&:before {
		width: 1px;
		background: #AAAAAA;
		left: 50%;
		top: -320px;
		height: 320px;
	}
	
	.eye {
		top: 16px;
		height: 14px;
		width: 12px;
		background: #FFFFFF;
		@include border-radius(50%);
		
		&:after {
			top: 6px;
			height: 5px;
			width: 5px;
			@include border-radius(50%);
			background: black;
		}
		
		&.left {
			left: 14px;
			
			&:after {
				right: 3px;
			}
		}
		
		&.right {
			right: 14px;
			
			&:after {
				left: 3px;
			}
		}
	}
	
	.leg {
		top: 6px;
		height: 12px;
		width: 14px;
		border-top: 2px solid #110D04;
		border-left: 1px solid transparent;
		border-right: 1px solid transparent;
		border-bottom: 1px solid transparent;
		z-index: -1;
		
		&.left {
			left: -8px;
			@include transform-origin(top, right);
			@include transform(rotate(36deg) skewX(-20deg));
			border-left: 2px solid #110D04;
			@include border-radius(60% 0 0 0 );
			@include animation(legs-wriggle-left 1s 0s infinite);
		}
		
		&.right {
			right: -8px;
			@include transform-origin(top, left);
			@include transform(rotate(-36deg) skewX(20deg));
			border-right: 2px solid #110D04;
			@include border-radius(0 60% 0 0 );
			@include animation(legs-wriggle-right 1s 0.2s infinite);
		}
		
		&:nth-of-type(2)  {
			top: 14px;
			left: -11px;
			@include animation(legs-wriggle-left 1s 0.8s infinite);
		}
		
		&:nth-of-type(3)  {
			top: 22px;
			left: -12px;
			@include animation(legs-wriggle-left 1s 0.2s infinite);
		}
		
		&:nth-of-type(4)  {
			top: 31px;
			left: -10px;
			@include animation(legs-wriggle-left 1s 0.4s infinite);
		}
		
		&:nth-of-type(6)  {
			top: 14px;
			right: -11px;
			@include animation(legs-wriggle-right 1s 0.4s infinite);
		}
		
		&:nth-of-type(7)  {
			top: 22px;
			right: -12px;
			@include animation(legs-wriggle-right 1s 0.7s infinite);
		}
		
		&:nth-of-type(8)  {
			top: 31px;
			right: -10px;
			@include animation(legs-wriggle-right 1s 0.3s infinite);
		}
	}
}

.spider_0  {
	left: 5%;
	@include animation(spider-move-0 5s infinite);
}

.spider_1  {
	left: 20%;
	@include animation(spider-move-1 5s infinite);
}

.spider_2  {
	left: 35%;
	@include animation(spider-move-2 5s infinite);
}

.spider_3  {
	right: 35%;
	margin-top: 160px;
	@include animation(spider-move-3 5s infinite);
}

.spider_4  {
	right: 20%;
	margin-top: 50px;
	@include animation(spider-move-4 5s infinite);
}

.spider_5  {
	right: 5%;
	margin-top: 210px;
	@include animation(spider-move-5 5s infinite);
}

h1 {
	position: absolute;
	left: 6%;
	bottom: 12%;
	font-family: 'Eater', cursive;
	font-size: 8.5vw;
	color: #111111;
	@include animation(flicker 4s 0s infinite);
}

.web-right {
	position: absolute;
	height: 200px;
	width: auto;
	right: -10px;
	top: -10px;
	z-index: -1;
	opacity: 0.2;
}

.web-left {
	position: absolute;
	left: -10px;
	top: -10px;
	@include transform(rotate(-90deg));
	z-index: -1;
	opacity: 0.2;
}

@include keyframes(flicker) {
	0%, 6%, 12% {
		text-shadow: none;
		color: #111111;
	}
	3%, 9% {
		text-shadow: 0 0 8px rgba(#fa6701,0.6);
		color: #fa6701;
	}
	60% {
		text-shadow: 0 0 8px rgba(#fa6701,0.6),
		 0 0 16px rgba(#fa6701,0.4), 
		 0 0 20px rgba(255,0,84,0.2), 
		 0 0 22px rgba(255,0,84,0.1);
		color: #fa6701;
	}
	100% {
		text-shadow: 0 0 8px rgba(#fa6701,0.6),
		 0 0 16px rgba(#fa6701,0.4), 
		 0 0 20px rgba(255,0,84,0.2), 
		 0 0 22px rgba(255,0,84,0.1);
		color: #fa6701;
	}
}

@include keyframes(legs-wriggle-left) {
	0%, 100% {
		@include transform(rotate(36deg) skewX(-20deg));
	}
	25%, 75% {
		@include transform(rotate(15deg) skewX(-20deg));
	}
	50% {
		@include transform(rotate(45deg) skewX(-20deg));
	}
}

@include keyframes(legs-wriggle-right) {
	0%, 100% {
		@include transform(rotate(-36deg) skewX(20deg));
	}
	25%, 75% {
		@include transform(rotate(-15deg) skewX(20deg));
	}
	50% {
		@include transform(rotate(-45deg) skewX(20deg));
	}
}

$n: 6;
@for $i from 0 to $n {
	$height: random(190) + 40 + "px";
	$movement: random(100) + 20 + "px";
	$random-percentage: random(40) + 30 + "%";
	
	@include keyframes(spider-move-#{$i}) {
		0%, 100% {
			margin-top: #{$height};
		}
		#{$random-percentage} {
			margin-top: calc(#{$height} + #{$movement});
		}
	}
}

Html part...






5. Rainbow Spider



Following is the JavaScript Code


!function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i}({1:[function(require,module,exports){var VerletJS=require("./verlet");var constraint=require("./constraint");require("./objects");window.Vec2=require("./vec2");window.VerletJS=VerletJS;window.Particle=VerletJS.Particle;window.DistanceConstraint=constraint.DistanceConstraint;window.PinConstraint=constraint.PinConstraint;window.AngleConstraint=constraint.AngleConstraint},{"./verlet":2,"./constraint":3,"./objects":4,"./vec2":5}],3:[function(require,module,exports){exports.DistanceConstraint=DistanceConstraint;exports.PinConstraint=PinConstraint;exports.AngleConstraint=AngleConstraint;function DistanceConstraint(a,b,stiffness,distance){this.a=a;this.b=b;this.distance=typeof distance!="undefined"?distance:a.pos.sub(b.pos).length();this.stiffness=stiffness}DistanceConstraint.prototype.relax=function(stepCoef){var normal=this.a.pos.sub(this.b.pos);var m=normal.length2();normal.mutableScale((this.distance*this.distance-m)/m*this.stiffness*stepCoef);this.a.pos.mutableAdd(normal);this.b.pos.mutableSub(normal)};DistanceConstraint.prototype.draw=function(ctx){ctx.beginPath();ctx.moveTo(this.a.pos.x,this.a.pos.y);ctx.lineTo(this.b.pos.x,this.b.pos.y);ctx.strokeStyle="#d8dde2";ctx.stroke()};function PinConstraint(a,pos){this.a=a;this.pos=(new Vec2).mutableSet(pos)}PinConstraint.prototype.relax=function(stepCoef){this.a.pos.mutableSet(this.pos)};PinConstraint.prototype.draw=function(ctx){ctx.beginPath();ctx.arc(this.pos.x,this.pos.y,6,0,2*Math.PI);ctx.fillStyle="rgba(0,153,255,0.1)";ctx.fill()};function AngleConstraint(a,b,c,stiffness){this.a=a;this.b=b;this.c=c;this.angle=this.b.pos.angle2(this.a.pos,this.c.pos);this.stiffness=stiffness}AngleConstraint.prototype.relax=function(stepCoef){var angle=this.b.pos.angle2(this.a.pos,this.c.pos);var diff=angle-this.angle;if(diff<=-Math.PI)diff+=2*Math.PI;else if(diff>=Math.PI)diff-=2*Math.PI;diff*=stepCoef*this.stiffness;this.a.pos=this.a.pos.rotate(this.b.pos,diff);this.c.pos=this.c.pos.rotate(this.b.pos,-diff);this.b.pos=this.b.pos.rotate(this.a.pos,diff);this.b.pos=this.b.pos.rotate(this.c.pos,-diff)};AngleConstraint.prototype.draw=function(ctx){ctx.beginPath();ctx.moveTo(this.a.pos.x,this.a.pos.y);ctx.lineTo(this.b.pos.x,this.b.pos.y);ctx.lineTo(this.c.pos.x,this.c.pos.y);var tmp=ctx.lineWidth;ctx.lineWidth=5;ctx.strokeStyle="rgba(255,255,0,0.2)";ctx.stroke();ctx.lineWidth=tmp}},{}],5:[function(require,module,exports){module.exports=Vec2;function Vec2(x,y){this.x=x||0;this.y=y||0}Vec2.prototype.add=function(v){return new Vec2(this.x+v.x,this.y+v.y)};Vec2.prototype.sub=function(v){return new Vec2(this.x-v.x,this.y-v.y)};Vec2.prototype.mul=function(v){return new Vec2(this.x*v.x,this.y*v.y)};Vec2.prototype.div=function(v){return new Vec2(this.x/v.x,this.y/v.y)};Vec2.prototype.scale=function(coef){return new Vec2(this.x*coef,this.y*coef)};Vec2.prototype.mutableSet=function(v){this.x=v.x;this.y=v.y;return this};Vec2.prototype.mutableAdd=function(v){this.x+=v.x;this.y+=v.y;return this};Vec2.prototype.mutableSub=function(v){this.x-=v.x;this.y-=v.y;return this};Vec2.prototype.mutableMul=function(v){this.x*=v.x;this.y*=v.y;return this};Vec2.prototype.mutableDiv=function(v){this.x/=v.x;this.y/=v.y;return this};Vec2.prototype.mutableScale=function(coef){this.x*=coef;this.y*=coef;return this};Vec2.prototype.equals=function(v){return this.x==v.x&&this.y==v.y};Vec2.prototype.epsilonEquals=function(v,epsilon){return Math.abs(this.x-v.x)<=epsilon&&Math.abs(this.y-v.y)<=epsilon};Vec2.prototype.length=function(v){return Math.sqrt(this.x*this.x+this.y*this.y)};Vec2.prototype.length2=function(v){return this.x*this.x+this.y*this.y};Vec2.prototype.dist=function(v){return Math.sqrt(this.dist2(v))};Vec2.prototype.dist2=function(v){var x=v.x-this.x;var y=v.y-this.y;return x*x+y*y};Vec2.prototype.normal=function(){var m=Math.sqrt(this.x*this.x+this.y*this.y);return new Vec2(this.x/m,this.y/m)};Vec2.prototype.dot=function(v){return this.x*v.x+this.y*v.y};Vec2.prototype.angle=function(v){return Math.atan2(this.x*v.y-this.y*v.x,this.x*v.x+this.y*v.y)};Vec2.prototype.angle2=function(vLeft,vRight){return vLeft.sub(this).angle(vRight.sub(this))};Vec2.prototype.rotate=function(origin,theta){var x=this.x-origin.x;var y=this.y-origin.y;return new Vec2(x*Math.cos(theta)-y*Math.sin(theta)+origin.x,x*Math.sin(theta)+y*Math.cos(theta)+origin.y)};Vec2.prototype.toString=function(){return"("+this.x+", "+this.y+")"};function test_Vec2(){var assert=function(label,expression){console.log("Vec2("+label+"): "+(expression==true?"PASS":"FAIL"));if(expression!=true)throw"assertion failed"};assert("equality",new Vec2(5,3).equals(new Vec2(5,3)));assert("epsilon equality",new Vec2(1,2).epsilonEquals(new Vec2(1.01,2.02),.03));assert("epsilon non-equality",!new Vec2(1,2).epsilonEquals(new Vec2(1.01,2.02),.01));assert("addition",new Vec2(1,1).add(new Vec2(2,3)).equals(new Vec2(3,4)));assert("subtraction",new Vec2(4,3).sub(new Vec2(2,1)).equals(new Vec2(2,2)));assert("multiply",new Vec2(2,4).mul(new Vec2(2,1)).equals(new Vec2(4,4)));assert("divide",new Vec2(4,2).div(new Vec2(2,2)).equals(new Vec2(2,1)));assert("scale",new Vec2(4,3).scale(2).equals(new Vec2(8,6)));assert("mutable set",new Vec2(1,1).mutableSet(new Vec2(2,3)).equals(new Vec2(2,3)));assert("mutable addition",new Vec2(1,1).mutableAdd(new Vec2(2,3)).equals(new Vec2(3,4)));assert("mutable subtraction",new Vec2(4,3).mutableSub(new Vec2(2,1)).equals(new Vec2(2,2)));assert("mutable multiply",new Vec2(2,4).mutableMul(new Vec2(2,1)).equals(new Vec2(4,4)));assert("mutable divide",new Vec2(4,2).mutableDiv(new Vec2(2,2)).equals(new Vec2(2,1)));assert("mutable scale",new Vec2(4,3).mutableScale(2).equals(new Vec2(8,6)));assert("length",Math.abs(new Vec2(4,4).length()-5.65685)<=1e-5);assert("length2",new Vec2(2,4).length2()==20);assert("dist",Math.abs(new Vec2(2,4).dist(new Vec2(3,5))-1.4142135)<=1e-6);assert("dist2",new Vec2(2,4).dist2(new Vec2(3,5))==2);var normal=new Vec2(2,4).normal();assert("normal",Math.abs(normal.length()-1)<=1e-5&&normal.epsilonEquals(new Vec2(.4472,.89443),1e-4));assert("dot",new Vec2(2,3).dot(new Vec2(4,1))==11);assert("angle",new Vec2(0,-1).angle(new Vec2(1,0))*(180/Math.PI)==90);assert("angle2",new Vec2(1,1).angle2(new Vec2(1,0),new Vec2(2,1))*(180/Math.PI)==90);assert("rotate",new Vec2(2,0).rotate(new Vec2(1,0),Math.PI/2).equals(new Vec2(1,1)));assert("toString",new Vec2(2,4)=="(2, 4)")}},{}],4:[function(require,module,exports){var VerletJS=require("./verlet");var Particle=VerletJS.Particle;var constraints=require("./constraint");var DistanceConstraint=constraints.DistanceConstraint;VerletJS.prototype.point=function(pos){var composite=new this.Composite;composite.particles.push(new Particle(pos));this.composites.push(composite);return composite};VerletJS.prototype.lineSegments=function(vertices,stiffness){var i;var composite=new this.Composite;for(i in vertices){composite.particles.push(new Particle(vertices[i]));if(i>0)composite.constraints.push(new DistanceConstraint(composite.particles[i],composite.particles[i-1],stiffness))}this.composites.push(composite);return composite};VerletJS.prototype.cloth=function(origin,width,height,segments,pinMod,stiffness){var composite=new this.Composite;var xStride=width/segments;var yStride=height/segments;var x,y;for(y=0;y<segments;++y){for(x=0;x<segments;++x){var px=origin.x+x*xStride-width/2+xStride/2;var py=origin.y+y*yStride-height/2+yStride/2;composite.particles.push(new Particle(new Vec2(px,py)));if(x>0)composite.constraints.push(new DistanceConstraint(composite.particles[y*segments+x],composite.particles[y*segments+x-1],stiffness));if(y>0)composite.constraints.push(new DistanceConstraint(composite.particles[y*segments+x],composite.particles[(y-1)*segments+x],stiffness))}}for(x=0;x<segments;++x){if(x%pinMod==0)composite.pin(x)}this.composites.push(composite);return composite};VerletJS.prototype.tire=function(origin,radius,segments,spokeStiffness,treadStiffness){var stride=2*Math.PI/segments;var i;var composite=new this.Composite;for(i=0;i<segments;++i){var theta=i*stride;composite.particles.push(new Particle(new Vec2(origin.x+Math.cos(theta)*radius,origin.y+Math.sin(theta)*radius)))}var center=new Particle(origin);composite.particles.push(center);for(i=0;i<segments;++i){composite.constraints.push(new DistanceConstraint(composite.particles[i],composite.particles[(i+1)%segments],treadStiffness));composite.constraints.push(new DistanceConstraint(composite.particles[i],center,spokeStiffness));composite.constraints.push(new DistanceConstraint(composite.particles[i],composite.particles[(i+5)%segments],treadStiffness))}this.composites.push(composite);return composite}},{"./verlet":2,"./constraint":3}],2:[function(require,module,exports){window.requestAnimFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1e3/60)};var Vec2=require("./vec2");exports=module.exports=VerletJS;exports.Particle=Particle;exports.Composite=Composite;function Particle(pos){this.pos=(new Vec2).mutableSet(pos);this.lastPos=(new Vec2).mutableSet(pos)}Particle.prototype.draw=function(ctx){ctx.beginPath();ctx.arc(this.pos.x,this.pos.y,2,0,2*Math.PI);ctx.fillStyle="#2dad8f";ctx.fill()};function VerletJS(width,height,canvas){this.width=width;this.height=height;this.canvas=canvas;this.ctx=canvas.getContext("2d");this.mouse=new Vec2(0,0);this.mouseDown=false;this.draggedEntity=null;this.selectionRadius=20;this.highlightColor="#4f545c";this.bounds=function(particle){if(particle.pos.y>this.height-1)particle.pos.y=this.height-1;if(particle.pos.x<0)particle.pos.x=0;if(particle.pos.x>this.width-1)particle.pos.x=this.width-1};var _this=this;this.canvas.oncontextmenu=function(e){e.preventDefault()};this.canvas.onmousedown=function(e){_this.mouseDown=true;var nearest=_this.nearestEntity();if(nearest){_this.draggedEntity=nearest}};this.canvas.onmouseup=function(e){_this.mouseDown=false;_this.draggedEntity=null};this.canvas.onmousemove=function(e){var rect=_this.canvas.getBoundingClientRect();_this.mouse.x=e.clientX-rect.left;_this.mouse.y=e.clientY-rect.top};this.gravity=new Vec2(0,.2);this.friction=.99;this.groundFriction=.8;this.composites=[]}VerletJS.prototype.Composite=Composite;function Composite(){this.particles=[];this.constraints=[];this.drawParticles=null;this.drawConstraints=null}Composite.prototype.pin=function(index,pos){pos=pos||this.particles[index].pos;var pc=new PinConstraint(this.particles[index],pos);this.constraints.push(pc);return pc};VerletJS.prototype.frame=function(step){var i,j,c;for(c in this.composites){for(i in this.composites[c].particles){var particles=this.composites[c].particles;var velocity=particles[i].pos.sub(particles[i].lastPos).scale(this.friction);if(particles[i].pos.y>=this.height-1&&velocity.length2()>1e-6){var m=velocity.length();velocity.x/=m;velocity.y/=m;velocity.mutableScale(m*this.groundFriction)}particles[i].lastPos.mutableSet(particles[i].pos);particles[i].pos.mutableAdd(this.gravity);particles[i].pos.mutableAdd(velocity)}}if(this.draggedEntity)this.draggedEntity.pos.mutableSet(this.mouse);var stepCoef=1/step;for(c in this.composites){var constraints=this.composites[c].constraints;for(i=0;i<step;++i)for(j in constraints)constraints[j].relax(stepCoef)}for(c in this.composites){var particles=this.composites[c].particles;for(i in particles)this.bounds(particles[i])}};VerletJS.prototype.draw=function(){var i,c;this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);for(c in this.composites){if(this.composites[c].drawConstraints){this.composites[c].drawConstraints(this.ctx,this.composites[c])}else{var constraints=this.composites[c].constraints;for(i in constraints)constraints[i].draw(this.ctx)}if(this.composites[c].drawParticles){this.composites[c].drawParticles(this.ctx,this.composites[c])}else{var particles=this.composites[c].particles;for(i in particles)particles[i].draw(this.ctx)}}var nearest=this.draggedEntity||this.nearestEntity();if(nearest){this.ctx.beginPath();this.ctx.arc(nearest.pos.x,nearest.pos.y,8,0,2*Math.PI);this.ctx.strokeStyle=this.highlightColor;this.ctx.stroke()}};VerletJS.prototype.nearestEntity=function(){var c,i;var d2Nearest=0;var entity=null;var constraintsNearest=null;for(c in this.composites){var particles=this.composites[c].particles;for(i in particles){var d2=particles[i].pos.dist2(this.mouse);if(d2<=this.selectionRadius*this.selectionRadius&&(entity==null||d2<d2Nearest)){entity=particles[i];constraintsNearest=this.composites[c].constraints;d2Nearest=d2}}}for(i in constraintsNearest)if(constraintsNearest[i]instanceof PinConstraint&&constraintsNearest[i].a==entity)entity=constraintsNearest[i];return entity}},{"./vec2":5}]},{},[1]);

function getViewport() {

 var viewPortWidth;
 var viewPortHeight;

 // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
 if (typeof window.innerWidth != 'undefined') {
   viewPortWidth = window.innerWidth,
   viewPortHeight = window.innerHeight
 }

// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
 else if (typeof document.documentElement != 'undefined'
 && typeof document.documentElement.clientWidth !=
 'undefined' && document.documentElement.clientWidth != 0) {
    viewPortWidth = document.documentElement.clientWidth,
    viewPortHeight = document.documentElement.clientHeight
 }

 // older versions of IE
 else {
   viewPortWidth = document.getElementsByTagName('body')[0].clientWidth,
   viewPortHeight = document.getElementsByTagName('body')[0].clientHeight
 }
 return [viewPortWidth, viewPortHeight];
}

VerletJS.prototype.spider = function(origin) {
		var i;
		var legSeg1Stiffness = 0.99;
		var legSeg2Stiffness = 0.99;
		var legSeg3Stiffness = 0.99;
		var legSeg4Stiffness = 0.99;
		
		var joint1Stiffness = 1;
		var joint2Stiffness = 0.4;
		var joint3Stiffness = 0.9;
		
		var bodyStiffness = 1;
		var bodyJointStiffness = 1;
		
		var composite = new this.Composite();
		composite.legs = [];
		
		
		composite.thorax = new Particle(origin);
		composite.head = new Particle(origin.add(new Vec2(0,-5)));
		composite.abdomen = new Particle(origin.add(new Vec2(0,10)));
		
		composite.particles.push(composite.thorax);
		composite.particles.push(composite.head);
		composite.particles.push(composite.abdomen);
		
		composite.constraints.push(new DistanceConstraint(composite.head, composite.thorax, bodyStiffness));
		
		
		composite.constraints.push(new DistanceConstraint(composite.abdomen, composite.thorax, bodyStiffness));
		composite.constraints.push(new AngleConstraint(composite.abdomen, composite.thorax, composite.head, 0.4));
		
		
		// legs
		for (i=0;i<4;++i) {
			composite.particles.push(new Particle(composite.particles[0].pos.add(new Vec2(3,(i-1.5)*3))));
			composite.particles.push(new Particle(composite.particles[0].pos.add(new Vec2(-3,(i-1.5)*3))));
			
			var len = composite.particles.length;
			
			composite.constraints.push(new DistanceConstraint(composite.particles[len-2], composite.thorax, legSeg1Stiffness));
			composite.constraints.push(new DistanceConstraint(composite.particles[len-1], composite.thorax, legSeg1Stiffness));
			
			
			var lenCoef = 1;
			if (i == 1 || i == 2)
				lenCoef = 0.7;
			else if (i == 3)
				lenCoef = 0.9;
			
			composite.particles.push(new Particle(composite.particles[len-2].pos.add((new Vec2(20,(i-1.5)*30)).normal().mutableScale(20*lenCoef))));
			composite.particles.push(new Particle(composite.particles[len-1].pos.add((new Vec2(-20,(i-1.5)*30)).normal().mutableScale(20*lenCoef))));
			
			len = composite.particles.length;
			composite.constraints.push(new DistanceConstraint(composite.particles[len-4], composite.particles[len-2], legSeg2Stiffness));
			composite.constraints.push(new DistanceConstraint(composite.particles[len-3], composite.particles[len-1], legSeg2Stiffness));
			
			composite.particles.push(new Particle(composite.particles[len-2].pos.add((new Vec2(20,(i-1.5)*50)).normal().mutableScale(20*lenCoef))));
			composite.particles.push(new Particle(composite.particles[len-1].pos.add((new Vec2(-20,(i-1.5)*50)).normal().mutableScale(20*lenCoef))));
			
			len = composite.particles.length;
			composite.constraints.push(new DistanceConstraint(composite.particles[len-4], composite.particles[len-2], legSeg3Stiffness));
			composite.constraints.push(new DistanceConstraint(composite.particles[len-3], composite.particles[len-1], legSeg3Stiffness));
			
			
			var rightFoot = new Particle(composite.particles[len-2].pos.add((new Vec2(20,(i-1.5)*100)).normal().mutableScale(12*lenCoef)));
			var leftFoot = new Particle(composite.particles[len-1].pos.add((new Vec2(-20,(i-1.5)*100)).normal().mutableScale(12*lenCoef)))
			composite.particles.push(rightFoot);
			composite.particles.push(leftFoot);
			
			composite.legs.push(rightFoot);
			composite.legs.push(leftFoot);
			
			len = composite.particles.length;
			composite.constraints.push(new DistanceConstraint(composite.particles[len-4], composite.particles[len-2], legSeg4Stiffness));
			composite.constraints.push(new DistanceConstraint(composite.particles[len-3], composite.particles[len-1], legSeg4Stiffness));
			
			
			composite.constraints.push(new AngleConstraint(composite.particles[len-6], composite.particles[len-4], composite.particles[len-2], joint3Stiffness));
			composite.constraints.push(new AngleConstraint(composite.particles[len-6+1], composite.particles[len-4+1], composite.particles[len-2+1], joint3Stiffness));
			
			composite.constraints.push(new AngleConstraint(composite.particles[len-8], composite.particles[len-6], composite.particles[len-4], joint2Stiffness));
			composite.constraints.push(new AngleConstraint(composite.particles[len-8+1], composite.particles[len-6+1], composite.particles[len-4+1], joint2Stiffness));
			
			composite.constraints.push(new AngleConstraint(composite.particles[0], composite.particles[len-8], composite.particles[len-6], joint1Stiffness));
			composite.constraints.push(new AngleConstraint(composite.particles[0], composite.particles[len-8+1], composite.particles[len-6+1], joint1Stiffness));
			
			composite.constraints.push(new AngleConstraint(composite.particles[1], composite.particles[0], composite.particles[len-8], bodyJointStiffness));
			composite.constraints.push(new AngleConstraint(composite.particles[1], composite.particles[0], composite.particles[len-8+1], bodyJointStiffness));
		}
		
		this.composites.push(composite);
		return composite;
	}
	
	VerletJS.prototype.spiderweb = function(origin, radius, segments, depth) {
		var stiffness = 0.6;
		var tensor = 0.3;
		var stride = (2*Math.PI)/segments;
		var n = segments*depth;
		var radiusStride = radius/n;
		var i, c;

		var composite = new this.Composite();

		// particles
		for (i=0;i<n;++i) {
			var theta = i*stride + Math.cos(i*0.4)*0.05 + Math.cos(i*0.05)*0.2;
			var shrinkingRadius = radius - radiusStride*i + Math.cos(i*0.1)*20;
			
			var offy = Math.cos(theta*2.1)*(radius/depth)*0.2;
			composite.particles.push(new Particle(new Vec2(origin.x + Math.cos(theta)*shrinkingRadius, origin.y + Math.sin(theta)*shrinkingRadius + offy)));
		}
		
		for (i=0;i<segments;i+=4)
			composite.pin(i);

		// constraints
		for (i=0;i<n-1;++i) {
			// neighbor
			composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[i+1], stiffness));
			
			// span rings
			var off = i + segments;
			if (off < n-1)
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[off], stiffness));
			else
				composite.constraints.push(new DistanceConstraint(composite.particles[i], composite.particles[n-1], stiffness));
		}
		
		
		composite.constraints.push(new DistanceConstraint(composite.particles[0], composite.particles[segments-1], stiffness));
		
		for (c in composite.constraints)
			composite.constraints[c].distance *= tensor;

		this.composites.push(composite);
		return composite;
	}
	
	//+ Jonas Raoni Soares Silva
	//@ http://jsfromhell.com/array/shuffle [v1.0]
	function shuffle(o) { //v1.0
		for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
		return o;
	}
	
	VerletJS.prototype.crawl = function(leg) {
		
		var stepRadius = 100;
		var minStepRadius = 35;
		
		var spiderweb = this.composites[0];
		var spider = this.composites[1];
		
		var theta = spider.particles[0].pos.angle2(spider.particles[0].pos.add(new Vec2(1,0)), spider.particles[1].pos);

		var boundry1 = (new Vec2(Math.cos(theta), Math.sin(theta)));
		var boundry2 = (new Vec2(Math.cos(theta+Math.PI/2), Math.sin(theta+Math.PI/2)));
		
		
		var flag1 = leg < 4 ? 1 : -1;
		var flag2 = leg%2 == 0 ? 1 : 0;
		
		var paths = [];
		
		var i;
		for (i in spiderweb.particles) {
			if (
				spiderweb.particles[i].pos.sub(spider.particles[0].pos).dot(boundry1)*flag1 >= 0
				&& spiderweb.particles[i].pos.sub(spider.particles[0].pos).dot(boundry2)*flag2 >= 0
			) {
				var d2 = spiderweb.particles[i].pos.dist2(spider.particles[0].pos);
				
				if (!(d2 >= minStepRadius*minStepRadius && d2 <= stepRadius*stepRadius))
					continue;

				var leftFoot = false;
				var j;
				for (j in spider.constraints) {
					var k;
					for (k=0;k<8;++k) {
						if (
							spider.constraints[j] instanceof DistanceConstraint
							&& spider.constraints[j].a == spider.legs[k]
							&& spider.constraints[j].b == spiderweb.particles[i])
						{
							leftFoot = true;
						}
					}
				}
				
				if (!leftFoot)
					paths.push(spiderweb.particles[i]);
			}
		}
		
		for (i in spider.constraints) {
			if (spider.constraints[i] instanceof DistanceConstraint && spider.constraints[i].a == spider.legs[leg]) {
				spider.constraints.splice(i, 1);
				break;
			}
		}
		
		if (paths.length > 0) {
			shuffle(paths);
			spider.constraints.push(new DistanceConstraint(spider.legs[leg], paths[0], 1, 0));
		}
	}
	
	window.onload = function() {
		var canvas = document.getElementById("web");

		// canvas dimensions
		var width = getViewport()[0] - 50;
		var height = getViewport()[1] - 50;

		// retina
		//var dpr = window.devicePixelRatio || 1;
    var dpr = 1;
		canvas.width = width*dpr;
		canvas.height = height*dpr;
		canvas.getContext("2d").scale(dpr, dpr);

		// simulation
		var sim = new VerletJS(width, height, canvas);
		
		// entities
		var spiderweb = sim.spiderweb(new Vec2(width/2,height/2), Math.min(width, height)/2, 20, 7);

		var spider = sim.spider(new Vec2(width/2,-300));    
		
		
		spiderweb.drawParticles = function(ctx, composite) {
			var i;
			for (i in composite.particles) {
				var point = composite.particles[i];
				ctx.beginPath();
				ctx.arc(point.pos.x, point.pos.y, 1.3, 0, 2*Math.PI);
				ctx.fillStyle = "#7AA"; 
        
        //"#" + Math.random().toString(16).slice(2, 8);
        
				ctx.fill();
			}
		}
			
			
		spider.drawConstraints = function(ctx, composite) {
			var i;

			ctx.beginPath();
			ctx.arc(spider.head.pos.x, spider.head.pos.y, 4, 0, 2*Math.PI);
			ctx.fillStyle = getColor(1);
			ctx.fill();
			
			ctx.beginPath();
			ctx.arc(spider.thorax.pos.x, spider.thorax.pos.y, 4, 0, 2*Math.PI);
			ctx.fill();
			
			ctx.beginPath();
			ctx.arc(spider.abdomen.pos.x, spider.abdomen.pos.y, 8, 0, 2*Math.PI);
			ctx.fill();
			
			for (i=3;i<composite.constraints.length;++i) {
				var constraint = composite.constraints[i];
				if (constraint instanceof DistanceConstraint) {
					ctx.beginPath();
					ctx.moveTo(constraint.a.pos.x, constraint.a.pos.y);
					ctx.lineTo(constraint.b.pos.x, constraint.b.pos.y);
					
					// draw legs
					if (
						(i >= 2 && i <= 4)
						|| (i >= (2*9)+1 && i <= (2*9)+2)
						|| (i >= (2*17)+1 && i <= (2*17)+2)
						|| (i >= (2*25)+1 && i <= (2*25)+2)
					) {
						ctx.save();
						constraint.draw(ctx);
						ctx.strokeStyle = getColor(2);
						ctx.lineWidth = 3;
						ctx.stroke();
						ctx.restore();
					} else if (
						(i >= 4 && i <= 6)
						|| (i >= (2*9)+3 && i <= (2*9)+4)
						|| (i >= (2*17)+3 && i <= (2*17)+4)
						|| (i >= (2*25)+3 && i <= (2*25)+4)
					) {
						ctx.save();
						constraint.draw(ctx);
						ctx.strokeStyle = getColor(3);
						ctx.lineWidth = 2;
						ctx.stroke();
						ctx.restore();
					} else if (
						(i >= 6 && i <= 8)
						|| (i >= (2*9)+5 && i <= (2*9)+6)
						|| (i >= (2*17)+5 && i <= (2*17)+6)
						|| (i >= (2*25)+5 && i <= (2*25)+6)
					) {
						ctx.save();
						ctx.strokeStyle = getColor(4);
						ctx.lineWidth = 1.5;
						ctx.stroke();
						ctx.restore();
					} else {
						ctx.strokeStyle = getColor(5);
						ctx.stroke();
					}
				}
			}
		}
		
		spider.drawParticles = function(ctx, composite) {
		}
		
		// animation loop
		var legIndex = 0;
		var loop = function() {
        ti++;
        
			if (Math.floor(Math.random()*4) == 0) {
				sim.crawl(((legIndex++)*3)%8);
			}
			
			sim.frame(16);
			sim.draw();
			requestAnimFrame(loop);
		};

		loop();
	};
  
  var ti = 0;
  var tc = [
    ["#661111","#661111","#4D1A1A","#332222","#1A2B2B"], //red
    ["#663311","#663311","#4D2A1A","#333022","#1A1A2B"], //orange
    ["#666611","#666611","#4D4D1A","#333322","#1A1A2B"], //yellow
    ["#116611","#116611","#1A4D1A","#223322","#2B1A2B"], //green
    ["#111166","#111166","#1A1A4D","#222233","#2B2B1A"], //blue
    ["#661166","#661166","#4D1A4D","#332233","#1A2B1A"], //purple
    ["#111166","#111166","#1A1A4D","#222233","#2B2B1A"], //blue
    ["#116611","#116611","#1A4D1A","#223322","#2B1A2B"], //green
    ["#666611","#666611","#4D4D1A","#333322","#1A1A2B"], //yellow
    ["#663311","#663311","#4D2A1A","#333022","#1A1A2B"], //orange
    ["#661111","#661111","#4D1A1A","#332222","#1A2B2B"] //red
  ];
  
  function getColor(part) {
    var col = "#661111";
    
    if (ti >= 999) {
      ti = 0;
    }
    
    var ts = Math.floor(ti/100);
    var ta = 200 - ((ti%100) * 2);
    
  switch (part) {
    case 1: col = shadeColor(tc[ts][0], ta); break;
    case 2: col = shadeColor(tc[ts][1], ta); break;
    case 3: col = shadeColor(tc[ts][2], ta); break;
    case 4: col = shadeColor(tc[ts][3], ta); break;
    case 5: col = shadeColor(tc[ts][4], ta); break;
  }
  return col;
}

function shadeColor(color, shade) {
    var colorInt = parseInt(color.substring(1),16);

    var R = (colorInt & 0xFF0000) >> 16;
    var G = (colorInt & 0x00FF00) >> 8;
    var B = (colorInt & 0x0000FF) >> 0;

    R = R + Math.floor((shade/255)*R);
    G = G + Math.floor((shade/255)*G);
    B = B + Math.floor((shade/255)*B);

    var newColorInt = (R<<16) + (G<<8) + (B);
    var newColorStr = "#"+newColorInt.toString(16);

    return newColorStr;
}

Html Part.







6. Spider Spring



Html.


CSS part.
@import url(https://fonts.googleapis.com/css?family=Poiret+One);
body{
  width:100%;
  margin:0;
  overflow:hidden;
  cursor:move;
  background:hsla(0,0%,10%,1);
}
window.requestAnimFrame = (function() {
  return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
})();

var c = null,
  $ = null,
  w,
  h;

var
  node = null,
  _arr = [],
  _cnt = 1,
  _s = 40,
  _ln = [],
  _num = 6;

var _spr = 0.1,
  _fric = 0.8,
  _grav = 0,
  _drag = 10,
  _tar = {};

var txt = function() {
  $.fillStyle = 'hsla(255,255%,255%,.4)';

  var t1 = "Spider Spring".split("").join(String.fromCharCode(0x2004));
  $.font = "5em Poiret One";
  $.fillText(t1, w / 2 - 350, h / 4 - 100);

  var t2 = "Mouse / Touch Drag && Release".split("").join(String.fromCharCode(0x2004));
  $.font = "1.5em Poiret One";
  $.fillText(t2, w / 2 - 250, h - 100);
   var t3 = "OR".split("").join(String.fromCharCode(0x2004));
  $.font = "1.5em Poiret One";
  $.fillText(t3, w / 2, h - 60);
  
  var t4 = "Click / Touch Anywhere && Hold".split("").join(String.fromCharCode(0x2004));
  $.font = "1.5em Poiret One";
  $.fillText(t4, w / 2 - 260, h - 25);
}

var rndCol = function() {
  var r = (Math.floor(Math.random() * 255));
  var g = (Math.floor(Math.random() * 255));
  var b = (Math.floor(Math.random() * 255));

  return 'rgba(' + r + ',' + g + ',' + b + ',' + '1)';
}

var go = function() {
  c = document.getElementById("canv");
  $ = c.getContext("2d");
  w = c.width = window.innerWidth;
  h = c.height = window.innerHeight;

  _tar.x = w / 2;
  _tar.y = h / 2;

  node = new Node($);
  node.r = Math.ceil(Math.random() * _s + 50);
  node.mass = (node.r - node.minR) / 10;

  for (var i = 0; i < _num; i++) {
    var _conn = new Node($);
    _conn.x = Math.random() * w;
    _conn.y = Math.random() * h;
    _conn.r = 20;
    _conn.mass = 0;
    _ln.push(_conn);
  }

  run();
};

var set = function() {
  for (var i = 0; i < _num; i++) {
    var a = _ln[i];
    _spring(node, a.x, a.y);
  }

  node.vy = node.vy * _fric;
  node.vx = node.vx * _fric;

  node.x += node.vx;
  node.y += node.vy;
  draw();
};

var _spring = function(node, tx, ty, r) {
  var dx = tx - node.x;
  var dy = ty - node.y;

  var tr = r || 0;

  var _ang = Math.atan2(dy, dx);

  var rx = (tr + node.r) * Math.cos(_ang);
  var ry = (tr + node.r) * Math.sin(_ang);

  var ax = dx * _spr;
  var ay = dy * _spr;

  node.vx += ax;
  node.vy += ay;
  node.vy += (_grav + node.mass);

  if (node._fl) {

    node.vx += node.daX;
    node.vy += node.daY;
  }
};

var Node = function() {
  this.anim.apply(this, arguments);
};

Node.prototype = {
  anim: function($, color) {
    this.$ = $;
    this.x = 0;
    this.y = 0;
    this.r = 20;

    this.minR = 10;
    this.beg = 0 * Math.PI / 180;
    this.fin = 360 * Math.PI / 180;
    this.color = rndCol();

    this.vx = 0;
    this.vy = 0;

    this._fl = true;
    this.daX = 0;
    this.daY = 0;
  },
  draw: function() {
    this.$.beginPath();
    this.$.shadowColor = 'hsla(0,0%,0%,.85)';
    this.$.shadowBlur = 30;
    this.$.shadowOffsetX = 8;
    this.$.shadowOffsetY = 8;
    this.$.fillStyle = this.color;
    this.$.arc(this.x, this.y, this.r, this.beg, this.fin, true);
    this.$.fill();
  },
  drag: function(x, y) {
    var dx = x - this.x;
    var dy = y - this.y;

    var d = Math.sqrt(dx * dx + dy * dy) * 0.009;
    var _ang = Math.atan2(dy, dx);

    this.daX = _drag * d * Math.cos(_ang);
    this.daY = _drag * d * Math.sin(_ang);

  },
  hit: function(x, y) {
    var dx = x - this.x;
    var dy = y - this.y;

    var d = Math.sqrt(dx * dx + dy * dy);

    if (d > this.r) {
      this._fl = false;
      return false;
    } else {
      this._fl = true;
      return true;
    }
  }
};

var draw = function(mx, my) {
  $.clearRect(0, 0, w, h);
  $.save();
  $.fillStyle = 'hsla(0,0%,10%,1)';
  $.fillRect(0, 0, w, h);
  $.fill();
  txt();

  for (var i = 0; i < _num; i++) {

    var l = _ln[i];
    l.draw();
    $.beginPath();
    $.moveTo(l.x, l.y);
    $.lineTo(node.x, node.y);
    $.lineCap = 'round';
    $.lineWidth = 6;
    $.strokeStyle = 'hsla(255,255%,255%,.7)';
    $.stroke();
    $.closePath();
  }
  node.draw();
  $.restore();
};
var run = function() {
  window.requestAnimFrame(run);
  set();
}

window.addEventListener('mousedown', function(e) {
  _tar.x = e.clientX;
  _tar.y = e.clientY;
  node._fl = true;
  node.drag(e.clientX, e.clientY);
}, false);

window.addEventListener('mousemove', function(e) {
  node.drag(e.clientX, e.clientY);
}, false);

window.addEventListener('mouseup', function(e) {
  node._fl = false;
}, false);

window.addEventListener('touchstart', function(e) {
  _tar.x = e.touches[0].clientX;
  _tar.y = e.touches[0].clientY;
  node._fl = true;
  node.drag(e.touches[0].clientX, e.touches[0].clientY);
}, false);

window.addEventListener('touchmove', function(e) {
  node.drag(e.touches[0].clientX, e.touches[0].clientY);
}, false);

window.addEventListener('touchend', function(e) {
  node._fl = false;
}, false);

window.addEventListener('resize', function() {
  c.width = w = window.innerWidth;
  c.height = h = window.innerHeight;
  txt();
}.false);

go();

Post a Comment

1 Comments

Welcome! Please Comment Without Any Hesitation.
Thank You