DIR : /home/kozerus/public_html/jkwii/js/jsdoit/forked_skeleton_ani/index.js
/home/kozerus/public_html/jkwii/js/jsdoit/forked_skeleton_ani
var canvas = document.getElementById('id_canvas');
var dragging=false
var ctx=canvas.getContext("2d")
var mouse={x:0,y:0}
var mousePressed=false
canvas.onmousemove=function(e){ mouse={x:e.pageX-this.offsetLeft,y:e.pageY-this.offsetTop}}
canvas.onmousedown=function(){mousePressed=true;dragging=true}
canvas.onmouseup=function(){mousePressed=false;dragging=false}
function lerpColor(color1,color2,amnt){
ctx.fillStyle=color1
ctx.fillRect(0,0,1,1)
var data1=ctx.getImageData(0,0,1,1).data
ctx.fillStyle=color2
ctx.fillRect(0,0,1,1)
var data2=ctx.getImageData(0,0,1,1).data
var colr= parseInt(data1[0]*(1-amnt)+ data2[0]*( amnt))
var colg= parseInt(data1[1]*(1-amnt)+ data2[1]*( amnt))
var colb= parseInt(data1[2]*(1-amnt)+ data2[2]*( amnt))
return "rgb("+colr+","+colg+","+colb+")"
}
function color(r,g,b,a){
var G=g!=undefined&&b!=undefined?g:r
var B=g!=undefined&&b!=undefined?b:r
if(a){
return "rgba("+r+","+g+","+b+","+a+")"
}else{
return "rgb("+r+","+G+","+B+")"
}
}
function fill(c){ctx.fillStyle=c}
function stroke(c){ctx.strokeStyle=c}
function strokeWeight(w ){ctx.lineWidth=w}
function line(a,b,c,d){
ctx.beginPath()
ctx.moveTo(a,b)
ctx.lineTo(c,d)
ctx.stroke()
}
function quad(a,b,c,d,e,f,g,h){
ctx.beginPath()
ctx.moveTo(a,b)
ctx.lineTo(c,d)
ctx.lineTo(e,f)
ctx.lineTo(g,h)
ctx.lineTo(a,b)
ctx.stroke()
ctx.fill()
}
function ellipse(x,y,w,h){
ctx.beginPath()
if(w!=h){
var s=w>h?w:h
ctx.scale(w/s,h/s)
ctx.arc(x,y,w,0,6.28,false)
ctx.fill()
}else{
ctx.arc(x,y,w,0,6.28,false)
ctx.fill()
}
}
function constrain(a,b,c){
a=a<b?b:a
a=a>c?c:a
return a
}
function newArray(a,b,c){
var A=new Array(a)
if (b){for (i=0;i<a;i++)A[i]=new Array(b)}
if (c){for (i=0;i<a;i++)for (j=0;j<b;j++)A[i][j]=new Array(c)}
return A
}
function dist(a,b,c,d){return Math.sqrt((a-b)*(a-b)+(c-d)*(c-d))}
function random(a,b){return b?a+Math.random()*b:Math.random()*a}
function int(x){return parseInt(x)}
function float(x){return parseFloat(x)}
if ( !window.requestAnimationFrame ) {
window.requestAnimationFrame = ( function() {
return window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
window.setTimeout( callback, 1000 / 60 );
};
} )();
}
var width,height
function size(a,b,c){
c.width=a
c.height=b
width=a
height=b
}
function map(value, low1, high1, low2, high2){
var diff= high1-low1
var range=high2-low2
return (value/diff)*range+low2
}
function sq(x){
return x*x
}
function exp(x){
return Math.log(x)
}
;(function(win, doc) {
'use strict';
/**
* @class
* @constructor
*
* @param {string} label
* @param {number} length
* @param {number} deg
* @param {number} gain
* @param {Array.<Bone>?} opt_bones
*/
function Bone(label, length, deg, gain, opt_bones) {
this.label = label;
this.length = length;
this.gain = gain;
this.initialRotation = deg * Math.PI / 180;
this.destRotation = this.initialRotation;
this.curRotation = this.initialRotation * 1.2;
this.bones = opt_bones || this.bones;
}
Bone.prototype.bones = [];
Bone.prototype.rotate = rotate;
/**
* @param {number} rad
*/
function rotate(rad) {
var arr = this.bones,
i = arr.length;
rad *= this.gain;
this.destRotation += rad;
while (i--) {
arr[i].rotate(rad);
}
}
/////////////////////////////////////////////////
// Export
win.Bone = Bone;
}(this, document));
;(function(win, doc) {
'use strict';
/**
* @class
* @constructor
* @param {Array.<Bone>} bones
*/
function Skeleton(bones) {
this.bones = bones;
this.parts = labelParts(bones);
}
/**
* @param {Array.<Bone>} bones
* @param {Object.<Bone>?} opt_obj
* @return {Object.<Bone>}
*/
function labelParts(bones, opt_obj) {
var arr = bones,
len = arr.length,
i = 0,
obj = opt_obj || {},
itm;
for (; i < len; ++i) {
itm = arr[i];
obj[itm.label] = itm;
labelParts(itm.bones, obj);
}
return obj;
}
/////////////////////////////////////////////////
// Export
win.Skeleton = Skeleton;
}(this, document));
;(function(win, doc) {
'use strict';
/////////////////////////////////////////////////
/**
* @class
* @constructor
*/
function Canine() {
this.skeleton = new Skeleton([
new Bone('body', 150, 0, .2, [
new Bone('head', 60, -40, 8),
new Bone('fleftLeg', 60, 110, -2, [
new Bone('fleftLeg2', 80, -30, 2, [
new Bone('fleftLeg3', 20, -20, 2,[
new Bone('fleftFoot', 20, -50, .1)
])
])
]),
new Bone('frightLeg', 60, 110, 1, [
new Bone('frightLeg2', 80, -30, 1, [
new Bone('frightLeg3', 20, -20, 1,[
new Bone('frightFoot', 20, -50, .1)
])
])
])
]),
new Bone('leftLeg', 60, 70, -2, [
new Bone('leftLeg2', 80, 40, 1, [
new Bone('leftleg3', 20, -20, 1,[
new Bone('leftFoot', 30, -80, .1)
])
])
]),
new Bone('rightLeg', 60, 70, 2, [
new Bone('rightLeg2', 80, 40, 1, [
new Bone('rightLeg3', 20, -20, 1,[
new Bone('rightFoot', 30, -80, .1)
])
])
]),new Bone('tail', 20, -140, 1,[new Bone('tail2', 30, 10, 1)])
]);
}
Canine.prototype.x = 0;
Canine.prototype.y = 0;
Canine.prototype.initialOffsetY = 0;
Canine.prototype.destOffsetY = 0;
Canine.prototype.curOffsetY = -100;
Canine.prototype.update = update;
Canine.prototype.draw = draw;
/**
* @param {number} distance
*/
function update(distance) {
var OFFSET_Y_MAX = -10,
ROTATION_PHASE = 200,
ROTATION_GAIN = .04,
OFFSET_Y_PHASE = 100,
OFFSET_Y_GAIN = 3,
deltaRad;
deltaRad = Math.cos(Math.PI * 2 * (distance % ROTATION_PHASE) / ROTATION_PHASE) * ROTATION_GAIN;
this.skeleton.parts.body.rotate(deltaRad);
this.skeleton.parts.leftLeg.rotate(deltaRad);
this.skeleton.parts.rightLeg.rotate(deltaRad);
this.skeleton.parts.fleftLeg.rotate(deltaRad);
this.skeleton.parts.frightLeg.rotate(deltaRad);
this.skeleton.parts.fleftLeg2.rotate(deltaRad);
this.skeleton.parts.frightLeg2.rotate(deltaRad);
this.skeleton.parts.fleftLeg3.rotate(deltaRad);
this.skeleton.parts.frightLeg3.rotate(deltaRad);
this.skeleton.parts.tail.rotate(deltaRad);
this.skeleton.parts.tail2.rotate(deltaRad);
this.destOffsetY += Math.sin(Math.PI * 2 * (distance % OFFSET_Y_PHASE) / OFFSET_Y_PHASE) * OFFSET_Y_GAIN;
}
/**
* @param {CanvasRenderingContext2D} ctx
*/
function draw(ctx) {
var OFFSET_Y_SPRING_GAIN = .1,
OFFSET_Y_PROPORTIONAL_GAIN = .1,
ROTATION_SPRING_GAIN = .1,
ROTATION_PROPORTIONAL_GAIN = .1;
var arr = this.skeleton.bones,
i = arr.length;
ctx.save();
this.destOffsetY += (this.initialOffsetY - this.destOffsetY) * OFFSET_Y_SPRING_GAIN;
this.curOffsetY += (this.destOffsetY - this.curOffsetY) * OFFSET_Y_PROPORTIONAL_GAIN;
ctx.translate(this.x, this.y);
ctx.translate(0, this.curOffsetY);
while (i--) {
drawBone(arr[i]);
}
ctx.restore();
function drawBone(bone) {
var arr, i;
ctx.save();
bone.destRotation += (bone.initialRotation - bone.destRotation) * ROTATION_SPRING_GAIN;
bone.curRotation += (bone.destRotation - bone.curRotation ) * ROTATION_PROPORTIONAL_GAIN;
ctx.rotate(bone.curRotation);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(bone.length, 0);
ctx.stroke();
ctx.save();
ctx.translate(bone.length, 0);
arr = bone.bones;
i = arr.length;
while (i--) {
drawBone(arr[i]);
}
ctx.restore();
ctx.restore();
}
}
/////////////////////////////////////////////////
// Export
win.Canine = Canine;
}(this, document));
;(function(win, doc) {
'use strict';
/////////////////////////////////////////////////
/**
* @class
* @constructor
*/
function Human() {
this.skeleton = new Skeleton([
new Bone('body', 150, -80, .2, [
new Bone('head', 50, 20, 1),
new Bone('leftArm', 90, 190, -4, [
new Bone('leftArm2', 80, -50, 1)
]),
new Bone('rightArm', 90, 190, 4, [
new Bone('rightArm2', 80, -50, 1)
])
]),
new Bone('leftLeg', 100, 70, -1, [
new Bone('leftLeg2', 100, 40, 1, [
new Bone('leftFoot', 30, -110, .1)
])
]),
new Bone('rightLeg', 100, 70, 1, [
new Bone('rightLeg2', 100, 40, 1, [
new Bone('rightFoot', 30, -110, .1)
])
])
]);
}
Human.prototype.x = 0;
Human.prototype.y = 0;
Human.prototype.initialOffsetY = 0;
Human.prototype.destOffsetY = 0;
Human.prototype.curOffsetY = -100;
Human.prototype.update = update;
Human.prototype.draw = draw;
/**
* @param {number} distance
*/
function update(distance) {
var OFFSET_Y_MAX = -10,
ROTATION_PHASE = 200,
ROTATION_GAIN = .04,
OFFSET_Y_PHASE = 100,
OFFSET_Y_GAIN = 3,
deltaRad;
deltaRad = Math.cos(Math.PI * 2 * (distance % ROTATION_PHASE) / ROTATION_PHASE) * ROTATION_GAIN;
this.skeleton.parts.body.rotate(deltaRad);
this.skeleton.parts.leftLeg.rotate(deltaRad);
this.skeleton.parts.rightLeg.rotate(deltaRad);
this.destOffsetY += Math.sin(Math.PI * 2 * (distance % OFFSET_Y_PHASE) / OFFSET_Y_PHASE) * OFFSET_Y_GAIN;
}
/**
* @param {CanvasRenderingContext2D} ctx
*/
function draw(ctx) {
var OFFSET_Y_SPRING_GAIN = .1,
OFFSET_Y_PROPORTIONAL_GAIN = .1,
ROTATION_SPRING_GAIN = .1,
ROTATION_PROPORTIONAL_GAIN = .1;
var arr = this.skeleton.bones,
i = arr.length;
ctx.save();
this.destOffsetY += (this.initialOffsetY - this.destOffsetY) * OFFSET_Y_SPRING_GAIN;
this.curOffsetY += (this.destOffsetY - this.curOffsetY) * OFFSET_Y_PROPORTIONAL_GAIN;
ctx.translate(this.x, this.y);
ctx.translate(0, this.curOffsetY);
while (i--) {
drawBone(arr[i]);
}
ctx.restore();
function drawBone(bone) {
var arr, i;
ctx.save();
bone.destRotation += (bone.initialRotation - bone.destRotation) * ROTATION_SPRING_GAIN;
bone.curRotation += (bone.destRotation - bone.curRotation ) * ROTATION_PROPORTIONAL_GAIN;
ctx.rotate(bone.curRotation);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(bone.length, 0);
ctx.stroke();
ctx.save();
ctx.translate(bone.length, 0);
arr = bone.bones;
i = arr.length;
while (i--) {
drawBone(arr[i]);
}
ctx.restore();
ctx.restore();
}
}
/////////////////////////////////////////////////
// Export
win.Human = Human;
}(this, document));
;(function(win, doc) {
'use strict';
/////////////////////////////////////////////////
/**
* @class
* @constructor
*/
function Ground() {
this.surface = createSurface();
}
Ground.ROUGHNESS = 5;
Ground.LOOP_WIDTH = 465;
Ground.prototype.x = 0;
Ground.prototype.y = 0;
Ground.prototype.offsetX = 0;
Ground.prototype.draw = draw;
Ground.prototype.update = update;
/**
* @private
* @return {Array.<Object>}
*/
function createSurface() {
var len = 10,
i = 0,
ret = [];
for (i = 0; i < len; ++i) {
ret.push({
x : i * Ground.LOOP_WIDTH / len,
y : -Ground.ROUGHNESS * Math.random()
});
}
ret.push({
x : ret[0].x + Ground.LOOP_WIDTH,
y : ret[0].y
});
for (i = 0; i < len; ++i) {
ret.push({
x : ret[i].x + Ground.LOOP_WIDTH,
y : ret[i].y
});
}
ret.push({
x : ret[0].x + Ground.LOOP_WIDTH + Ground.LOOP_WIDTH,
y : ret[0].y
});
return ret;
}
/*
* @param {number} distance
*/
function update(distance) {
this.offsetX = distance % Ground.LOOP_WIDTH;
}
/**
* @param {CanvasRenderingContext2D} ctx
*/
function draw(ctx) {
var arr = this.surface,
i = arr.length,
p;
ctx.save();
ctx.translate(this.x, this.y);
ctx.translate(-this.offsetX, 0);
ctx.beginPath();
p = arr[--i];
ctx.moveTo(p.x, 20);
ctx.lineTo(p.x, p.y);
while (i--) {
p = arr[i];
ctx.lineTo(p.x, p.y);
}
ctx.lineTo(p.x, 20);
ctx.closePath();
ctx.fill();
ctx.restore();
}
/////////////////////////////////////////////////
// Export
win.Ground = Ground;
}(this, document));
;(function(win, doc) {
'use strict';
/////////////////////////////////////////////////
/**
* @class
* @constructor
*/
function Motion() {
this.startTime = null;
this.distance = 0;
}
Motion.VELOCITY = 300 / 1000;
Motion.prototype.start = start;
Motion.prototype.stop = stop;
Motion.prototype.update = update;
/**
*
*/
function start() {
this.startTime = +new Date;
this.progress = true;
}
/**
*
*/
function stop() {
this.progress = false;
}
/*
*
*/
function update() {
var curTime;
if (!this.progress) {
return;
}
curTime = +new Date;
this.distance += (curTime - this.startTime) * Motion.VELOCITY;
this.startTime = curTime;
}
/////////////////////////////////////////////////
// Export
win.Motion = Motion;
}(this, document));
(function(win, doc) {
'use strict';
var raf = win.requestAnimationFrame ||
win.webkitRequestAnimationFrame ||
win.mozRequestAnimationFrame ||
win.msRequestAnimationFrame ||
win.oRequestAnimationFrame ||
function(func) { setTimeout(func, 1000 / 60); };
var ARROW_RIGHT = 39,
cvs = canvas ,
ctx = cvs.getContext('2d'),
human = new Human,
dog=new Canine,
ground = new Ground,
motion = new Motion;
/////////////////////////////////////////////////
ground.x = 0;
ground.y = 426;
human.x = 90;
human.y = 240;
dog.x=200;
dog.y=265;
doc.addEventListener('keydown', handleKeyDown, true);
doc.addEventListener('keyup', handleKeyUp, true);
render();
/////////////////////////////////////////////////
/**
*
*/
function handleKeyDown(evt) {
switch (evt.keyCode) {
case ARROW_RIGHT :
motion.start();
break;
default :
break;
}
}
/**
*
*/
function handleKeyUp(evt) {
switch (evt.keyCode) {
case ARROW_RIGHT :
motion.stop();
break;
default :
break;
}
}
/**
*
*/
function render() {
cvs.width = cvs.height = 465;
if (motion.progress) {
motion.update();
human.update(motion.distance);
dog.update(motion.distance);
ground.update(motion.distance);
}
human.draw(ctx);
ground.draw(ctx);
dog.draw(ctx)
raf(render, cvs);
}
}(this, document));
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer