<!DOCTYPE html> |
<html> |
<head> |
<title>robot arm - inverse kinematics - Interactive DHTML demos</title> |
<meta name="Author" content="Gerard Ferrandez at http://www.dhteumeuleu.com"> |
<style type="text/css"> |
body { |
margin: 0px; |
padding: 0px; |
background: #111; |
width: 100%; |
height: 100%; |
color:#fff; |
font-size: 12px; |
font-family: arial,verdana; |
overflow: hidden; |
} |
#target { |
position: absolute; |
left: -999px; |
-webkit-transform: translate3d(0,0,0); // enable hardware acceleration in Webkit |
} |
#robots img { |
position: absolute; |
} |
#robot-1 { |
position:fixed; |
left:20%; |
top:0px; |
-webkit-transform: translate3d(0,0,0); // enable hardware acceleration in Webkit |
} |
#robot-2 { |
position:fixed; |
left:20%; |
bottom:0px; |
-webkit-transform: translate3d(0,0,0); |
} |
#robot-3 { |
position:fixed; |
left:80%; |
top:0px; |
-webkit-transform: translate3d(0,0,0); |
} |
#robot-4 { |
position:fixed; |
left:80%; |
bottom:0px; |
-webkit-transform: translate3d(0,0,0); |
} |
</style> |
<script type="text/javascript"> |
// =============================================================================== |
// ***** robot arm - inverse kinematics ***** |
// ----------------------------------------------------------------------------- |
// JavaScript: Gerard Ferrandez - 10 August 2011 |
// http://www.dhteumeuleu.com/ |
// Licensed under a CC-BY-NC license |
// ----------------------------------------------------------------------------- |
// cross-browser rotation CSS 2D Transforms (won't support IE < 9) |
// Tested OK on iPad 2: Hardware acceleration + touch-events supported |
// =============================================================================== |
"use strict"; |
(function () { |
// ----- private vars ----- |
var robots = []; |
var mouseX = 0, mouseY = 0, target, targetX = 0, targetY = 0, targetW = 0, targetH = 0; |
var transform, transformOrigin; |
// ----- Robot prototype ----- |
var Robot = function (span) { |
this.span = span; |
this.armSegments = []; |
this.numSegments = 1; |
this.y = 0; |
// ---- root ---- |
this.armSegments.push( |
new ArmSegment (this, false) |
); |
// ---- html defined arms ---- |
var s = span.getElementsByTagName("img"); |
for (var img, i = 0; img = s[i++];) { |
this.numSegments ++; |
this.armSegments.push( |
new ArmSegment (this, img) |
); |
} |
}; |
// ----- animation function ----- |
Robot.prototype.anim = function () { |
// ----- tracking mouse ----- |
var seg1 = this.armSegments[this.numSegments - 1]; |
seg1.x += (targetX - seg1.x - this.span.offsetLeft) * 0.075; |
seg1.y += (targetY - seg1.y - this.span.offsetTop) * 0.075; |
// ----- inverse kinematics ----- |
var i = this.numSegments - 1; |
while ( --i ) { |
// ---- bottom up chain ---- |
var seg0 = this.armSegments[i]; |
var seg1 = this.armSegments[i + 1]; |
var a = Math.atan2(seg0.y - seg1.y, seg0.x - seg1.x); |
seg0.x = seg1.x + Math.cos(a) * seg1.length; |
seg0.y = seg1.y + Math.sin(a) * seg1.length; |
} |
var i = 0, seg0, seg1; |
while ( seg0 = this.armSegments[i++]) { |
// ---- up bottom chain ---- |
if (i > 1) { |
var seg1 = this.armSegments[i - 2]; |
var a = seg0.a = Math.atan2(seg0.y - seg1.y, seg0.x - seg1.x); |
seg0.x = seg1.x + Math.cos(a) * seg0.length; |
seg0.y = seg1.y + Math.sin(a) * seg0.length; |
} |
// ---- CSS 2D transforms animation ----- |
// round values using bitewise hacks - see http://jsperf.com/math-round-vs-hack/3 |
if (seg0.img) { |
seg0.css[transform] = "translate(" |
+ ((0.5 + seg0.x - seg0.sx) | 0) + "px," |
+ ((0.5 + seg0.y - seg0.sy) | 0) + "px) rotate(" + seg0.a + "rad)"; |
seg0.css[transformOrigin] = ((0.5 + seg0.sx) | 0) + "px " |
+ ((0.5 + seg0.sy) | 0) + "px"; |
} |
} |
} |
// ----- Arm prototype ----- |
var ArmSegment = function(parent, img) { |
this.img = img; |
this.width = 0; |
this.length = 0; |
this.sx = 0; |
this.a = 0; |
this.x = 0; |
if (img) { |
this.css = img.style; |
this.sy = Math.round(img.height * 0.5); |
this.length = img.width - this.sy; |
this.sx = img.width; |
} |
this.y = parent.y; |
parent.y += this.length; |
} |
// ----- main loop ----- |
var run = function () { |
// ---- target ---- |
if (target) { |
targetX += (mouseX - targetX) * 0.2; |
targetY += (mouseY - targetY) * 0.2; |
target.left = ((targetX + 0.5 - targetW) | 0) + "px"; |
target.top = ((targetY + 0.5 - targetH) | 0) + "px"; |
} else { |
targetX = mouseX; |
targetY = mouseY; |
} |
// ---- robots ---- |
for (var r, i = 0; r = robots[i++];) { |
r.anim(); |
} |
}; |
//////////////////////////////////////////////////////////////////////////////////////// |
// ----- initialization ----- |
var init = function () { |
// ----- CSS3 2D transforms browsers prefix detection ----- |
var t = ["transform", "msTransform", "MozTransform", "WebkitTransform", "OTransform"]; |
for (var test, i = 0; test = t[i++];) { |
if (typeof document.body.style[test] != "undefined") { |
transform = test; |
transformOrigin = test + "Origin"; |
break; |
} |
} |
// ---- instanciate robot arms ---- |
var s = document.getElementById("robots").getElementsByTagName("span"); |
for (var r, i = 0; r = s[i++];) { |
robots.push( |
new Robot (r) |
); |
} |
// ---- target ---- |
target = document.getElementById("target"); |
if (target) { |
targetW = target.width / 2; |
targetH = target.height / 2; |
target = target.style; |
} |
// ---- mouse event ---- |
document.addEventListener('mousemove', function (e) { |
mouseX = e.clientX; |
mouseY = e.clientY; |
}, false); |
targetX = mouseX = window.innerWidth / 2; |
targetY = mouseY = window.innerHeight / 2; |
// ----- touch events ----- |
document.addEventListener('touchmove', function (e) { touchwk(e); }, false); |
document.addEventListener('touchstart', function (e) { touchwk(e); }, false); |
var touchwk = function (e) { |
e.preventDefault(); |
var touch = e.touches[0]; |
mouseX = touch.clientX; |
mouseY = touch.clientY; |
} |
// ----- start engine ----- |
if (transform) setInterval(run, 16); |
}; |
return { |
//////////////////////////////////////////////////////////////////////////// |
// ---- launch script ----- |
load : function (params) { |
window.addEventListener('load', function () { |
init(); |
}, false); |
} |
} |
})().load(); |
</script> |
</head> |
<body> |
<img id="target" src="../images/sp64r.gif" alt=""> |
<div id="robots"> |
<span id="robot-1"> |
<img src="../images/arm01.png" alt=""> |
<img src="../images/arm02.png" alt=""> |
<img src="../images/arm03.png" alt=""> |
<img src="../images/arm04.png" alt=""> |
</span> |
<span id="robot-2"> |
<img src="../images/arm01.png" alt=""> |
<img src="../images/arm02.png" alt=""> |
<img src="../images/arm03.png" alt=""> |
<img src="../images/arm04.png" alt=""> |
</span> |
<span id="robot-3"> |
<img src="../images/arm01.png" alt=""> |
<img src="../images/arm02.png" alt=""> |
<img src="../images/arm03.png" alt=""> |
<img src="../images/arm04.png" alt=""> |
</span> |
<span id="robot-4"> |
<img src="../images/arm01.png" alt=""> |
<img src="../images/arm02.png" alt=""> |
<img src="../images/arm03.png" alt=""> |
<img src="../images/arm04.png" alt=""> |
</span> |
</div> |
</body> |
</html> |
Translite
Jumat, 27 Januari 2012
Acces Denied
Langganan:
Postingan (Atom)