该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
此工具包包含:
1。包括对鼠标坐标,触屏坐标, 将颜色二进制或字符串转为rgb,对二进制颜色的检索, 3d图形绘制,2d图形绘制,
3d节点绘制, 生成飞船,速度向量。
建议中级开发者使用。
若使用请复制(含压缩版):
cantool.js:
/*
@Copyright David Gao(davidg0)
Made In China
canTool Version 1.0
canTool is an engine use to draw 2d and 3d points.Also included shipMaker,Ball3d,slider,mouse position and touch posision(for iPad or phones) and so on.
*/
//Animation requesting part for Opera Navigater Safari Chrome FireFox
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
function (callback) {
return window.setTimeout(callback, 17 );
});
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = (window.cancelRequestAnimationFrame ||
window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame ||
window.mozCancelAnimationFrame || window.mozCancelRequestAnimationFrame ||
window.msCancelAnimationFrame || window.msCancelRequestAnimationFrame ||
window.oCancelAnimationFrame || window.oCancelRequestAnimationFrame ||
window.clearTimeout);
}
//Objects part
function Ball3d(radius, color){
this.x = 0;
this.y = 0;
this.xpos = 0;
this.ypos = 0;
this.zpos = 0;
this.vx = 0;
this.vy = 0;
this.vz = 0;
this.radius = radius;
this.mass = 1;
this.rotation = 0;
this.scaleX = 1;
this.scaleY = 1;
this.color = tool.pColor(color);
this.lineWidth = 1;
this.visible = true;
}
Ball3d.prototype.draw = function(context){
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.fillStyle = this.color;
context.beginPath();
context.arc(0, 0, this.radius, 0, (Math.PI * 2), true);
context.closePath();
context.fill();
context.stroke();
context.restore();
};
function shipMaker(width, height){
this.x = 0;
this.y = 0;
this.width = width;
this.height = height;
this.rotation = 0;
}
shipMaker.prototype.draw = function(context){
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.lineWidth = 1;
context.strokeStyle = "white";
context.beginPath();
context.moveTo(10, 0);
context.lineTo(-10, 10);
context.lineTo(-5, 0);
context.lineTo(-10, -10);
context.lineTo(10, 0);
context.stroke();
if(this.showFlame){
context.beginPath();
context.moveTo(-7.5, -5);
context.lineTo(-15, 0);
context.lineTo(-7.5, 5);
context.stroke();
}
context.restore();
};
function Segment(width, height, widthL, color){
this.x = 0;
this.y = 0;
this.width = width;
this.height = height;
this.vx = 0;
this.vy = 0;
this.rotation = 0;
this.scaleX = 1;
this.scaleY = 1;
this.lineWidth = widthL
}
Segment.prototype.draw = function(context){
var h = this.height;
var d = this.width + h;
var cr = h / 2;
context.save();
context.translate(this.x, this.y);
context.rotate(this.rotation);
context.scale(this.scaleX, this.scaleY);
context.lineWidth = this.lineWidth;
context.beginPath();
context.moveTo(0, -cr);
context.lineTo(d - h, -cr);
context.quadraticCurveTo(-cr + d, -cr, -cr + d, 0);
context.lineTo(-cr + d, h - 2 * cr);
context.quadraticCurveTo(-cr + d, -cr + h, d - 2 * cr, -cr + h);
context.lineTo(0, -cr + h);
context.quadraticCurveTo(-cr, -cr + h, -cr, h - 2 * cr);
context.lineTo(-cr, 0);
context.quadraticCurveTo(-cr, -cr, 0, -cr);
context.closePath();
context.fill();
if(this.lineWidth > 0){
context.stroke();
}
};
function Slider(min, max, value){
this.onchange = null;
this.x = 0;
this.y = 0;
this.width = 16;
this.height = 100;
this.backWidth = 4;
this.backX = this.width / 2 - this.backWidth / 2;
this.handleHeight = 6;
this.handleY = 0;
this.updatePosition();
}
Slider.prototype.draw = function(context){
context.save();
context.translate(this.x, this.y);
context.beginPath();
context.fillRect(this.backX, 0, this.backWidth, this.height);
context.closePath();
context.beginPath();
context.rect(0, this.handleY, this.width, this.handleHeight);
context.closePath();
context.fill();
context.stroke();
context.restore();
};
Slider.prototype.updateValue = function(){
var old_value = this.value;
var handleRange = this.height - this.handleHeight;
var valueRange = this.max - this,min;
this.value = (handleRange - this.handleY) / handleRange * valueRange + this.min;
if(typepf this.onchange === *function* this.value !== old_value){
this.onchage();
}
};
Slider.prototype.updatePosition = function(){
var handleRange = this.height - this.handleHeight;
var valueRange = this.max - this.min;
this.handleY = handleRange - ((this.value - this.min) / valueRange) * handleRange;
};
Slider.prototype.captureMouse = function(element){
var self = this;
var mouse = utils.captureMouse(element);
bounds = [];
setHandleBounds();
element.addEventListener(*mousedown*, function() {
if(utils.containsPoint(bounds, mouse.x, mouse.y)){
element.addEventListener(*mouseup*, onMouseUp, false);
element.addEventListener(*mousemove*, onMouseMove, false);
}
}, false);
function onMouseUp(){
element.removeEventListener(*mousemove*, onMouseMove, false);
element.removeEventListener(*mouseup*, onMouseMove, false);
setHandleBounds();
}
function onMouseMove(){
var pos_y = mouse.y - self.y;
self.handleY = Math.min(self.height - self.handleHeight, Math.max(pos_y, 0));
self.updateValue();
}
function setHandleBounds(){
bounds.x = self.x;
bounds.y = self.y + self.handleY;
bounds.width = self.width;
bounds.height = self.handleHeight;
}
};
function Point3d(x, y, z){
this.x = x;
this.y = y;
this.z = z;
this.fl = 250;
this.vpx = 0;
this.vpy = 0;
this.vpz = 0;
this.cx = 0;
this.cy = 0;
this.cz = 0;
}
Point3d.prototype.setVanishingPoint = function(vpx, vpy){
this.vpx = vpx;
this.vpy = vpy;
};
Point3d.prototype.setCenter = function(cx, cy, cz){
this.cx = cx;
this.cy = cy;
this.cz = cz;
};
Point3d.prototype.rorateX = function(angleX){
var cosX = Math.cos(angleX);
var sinX = Math.sin(angleX);
var y1 = this.y * cosX - this.z * sinX;
var z1 = this.z * cosX + this.y * sinX;
this.y = y1;
this.z = z1;
};
Point3d.prototype.rotateY = function(angleY){
var cosY = Math.cos(angleY);
var sinY = Math.sin(angleY);
var x1 = this.x * cosY - this.z * sinY;
var z1 = this.z * cosY + this.x * sinY;
this.x = x1;
this.z = z1;
}
function Triangle (a, b, c, color) {
this.pointA = a;
this.pointB = b;
this.pointC = c;
this.color = (color === undefined) ? "#ff0000" : canTool.strColor(color);
this.lineWidth = 1;
this.alpha = 1;
}
Triangle.prototype.draw = function (context) {
if (this.isBackface()) {
return;
}
context.save();
context.lineWidth = this.lineWidth;
context.fillStyle = context.strokeStyle = utils.colorToRGB(this.color, this.alpha);
context.beginPath();
context.moveTo(this.pointA.getScreenX(), this.pointA.getScreenY());
context.lineTo(this.pointB.getScreenX(), this.pointB.getScreenY());
context.lineTo(this.pointC.getScreenX(), this.pointC.getScreenY());
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};
Triangle.prototype.getDepth = function () {
return Math.min(this.pointA.z, this.pointB.z, this.pointC.z);
};
Triangle.prototype.isBackface = function () {
var cax = this.pointC.getScreenX() - this.pointA.getScreenX(),
cay = this.pointC.getScreenY() - this.pointA.getScreenY(),
bcx = this.pointB.getScreenX() - this.pointC.getScreenX(),
bcy = this.pointB.getScreenY() - this.pointC.getScreenY();
return cax * bcy > cay * bcx;
};
function lightTriangle (a, b, c, color) {
this.pointA = a;
this.pointB = b;
this.pointC = c;
this.color = (color === undefined) ? "#ff0000" : canTool.strColor(color);
this.lineWidth = 1;
this.alpha = 1;
this.light = null;
}
lightTriangle.prototype.draw = function (context) {
if (this.isBackface()) {
return;
}
context.save();
context.lineWidth = this.lineWidth;
context.fillStyle = context.strokeStyle = this.getAdjustedColor();
context.beginPath();
context.moveTo(this.pointA.getScreenX(), this.pointA.getScreenY());
context.lineTo(this.pointB.getScreenX(), this.pointB.getScreenY());
context.lineTo(this.pointC.getScreenX(), this.pointC.getScreenY());
context.closePath();
context.fill();
if (this.lineWidth > 0) {
context.stroke();
}
context.restore();
};
lightTriangle.prototype.getDepth = function () {
return Math.min(this.pointA.z, this.pointB.z, this.pointC.z);
};
lightTriangle.prototype.isBackface = function () {
var cax = this.pointC.getScreenX() - this.pointA.getScreenX(),
cay = this.pointC.getScreenY() - this.pointA.getScreenY(),
bcx = this.pointB.getScreenX() - this.pointC.getScreenX(),
bcy = this.pointB.getScreenY() - this.pointC.getScreenY();
return cax * bcy > cay * bcx;
};
lightTriangle.prototype.getAdjustedColor = function () {
var color = utils.parseColor(this.color, true),
red = color >> 16,
green = color >> 8 & 0xff,
blue = color & 0xff,
lightFactor = this.getLightFactor();
red *= lightFactor;
green *= lightFactor;
blue *= lightFactor;
return utils.parseColor(red << 16 | green << 8 | blue);
};
lightTriangle.prototype.getLightFactor = function () {
var ab = {
x: this.pointA.x - this.pointB.x,
y: this.pointA.y - this.pointB.y,
z: this.pointA.z - this.pointB.z
};
var bc = {
x: this.pointB.x - this.pointC.x,
y: this.pointB.y - this.pointC.y,
z: this.pointB.z - this.pointC.z
};
var norm = {
x: (ab.y * bc.z) - (ab.z * bc.y),
y:-((ab.x * bc.z) - (ab.z * bc.x)),
z: (ab.x * bc.y) - (ab.y * bc.x)
};
var dotProd = norm.x * this.light.x +
norm.y * this.light.y +
norm.z * this.light.z,
normMag = Math.sqrt(norm.x * norm.x +
norm.y * norm.y +
norm.z * norm.z),
lightMag = Math.sqrt(this.light.x * this.light.x +
this.light.y * this.light.y +
this.light.z * this.light.z);
return (Math.acos(dotProd / (normMag * lightMag)) / Math.PI) * this.light.brightness;
};
function Light (x, y, z, brightness) {
this.x = (x === undefined) ? -100 : x;
this.y = (y === undefined) ? -100 : y;
this.z = (z === undefined) ? -100 : z;
this.brightness = (brightness === undefined) ? 1 : brightness;
}
Light.prototype.setBrightness = function (b) {
this.brightness = Math.min(Math.max(b, 0), 1);
};
//User*s part
var canTool = {};
window.canTool.strColor = function (color, toNumber) {
if (toNumber === true) {
if (typeof color === *number*) {
return (color | 0);
}
if (typeof color === *string* && color[0] === *#*) {
color = color.slice(1);
}
return window.parseInt(color, 16);
} else {
if (typeof color === *number*) {
color = *#* + (*00000* + (color | 0).toString(16)).substr(-6);
}
return color;
}
};
window.canTool.getMousePos = function (element) {
var mouse = {x: 0, y: 0, event: null},
body_scrollLeft = document.body.scrollLeft,
element_scrollLeft = document.documentElement.scrollLeft,
body_scrollTop = document.body.scrollTop,
element_scrollTop = document.documentElement.scrollTop,
offsetLeft = element.offsetLeft,
offsetTop = element.offsetTop;
element.addEventListener(*mousemove*, function (event) {
var x, y;
if (event.pageX || event.pageY) {
x = event.pageX;
y = event.pageY;
} else {
x = event.clientX + body_scrollLeft + element_scrollLeft;
y = event.clientY + body_scrollTop + element_scrollTop;
}
x -= offsetLeft;
y -= offsetTop;
mouse.x = x;
mouse.y = y;
mouse.event = event;
}, false);
return mouse;
};
window.canTool.getTouchPos = function (element) {
var touch = {x: null, y: null, isPressed: false, event: null},
body_scrollLeft = document.body.scrollLeft,
element_scrollLeft = document.documentElement.scrollLeft,
body_scrollTop = document.body.scrollTop,
element_scrollTop = document.documentElement.scrollTop,
offsetLeft = element.offsetLeft,
offsetTop = element.offsetTop;
element.addEventListener(*touchstart*, function (event) {
touch.isPressed = true;
touch.event = event;
}, false);
element.addEventListener(*touchend*, function (event) {
touch.isPressed = false;
touch.x = null;
touch.y = null;
touch.event = event;
}, false);
element.addEventListener(*touchmove*, function (event) {
var x, y,
touch_event = event.touches[0];
if (touch_event.pageX || touch_event.pageY) {
x = touch_event.pageX;
y = touch_event.pageY;
} else {
x = touch_event.clientX + body_scrollLeft + element_scrollLeft;
y = touch_event.clientY + body_scrollTop + element_scrollTop;
}
x -= offsetLeft;
y -= offsetTop;
touch.x = x;
touch.y = y;
touch.event = event;
}, false);
return touch;
};
window.canTool.colorToRGB = function (color, alpha) {
if (typeof color === *string* && color[0] === *#*) {
color = window.parseInt(color.slice(1), 16);
}
alpha = (alpha === undefined) ? 1 : alpha;
var r = color >> 16 & 0xff,
g = color >> 8 & 0xff,
b = color & 0xff,
a = (alpha < 0) ? 0 : ((alpha > 1) ? 1 : alpha);
if (a === 1) {
return "rgb("+ r +","+ g +","+ b +")";
} else {
return "rgba("+ r +","+ g +","+ b +","+ a +")";
}
};
window.canTool.containsPoint = function (rect, x, y) {
return !(x < rect.x ||
x > rect.x + rect.width ||
y < rect.y ||
y > rect.y + rect.height);
};
window.canTool.intersects = function (rectA, rectB) {
return !(rectA.x + rectA.width < rectB.x ||
rectB.x + rectB.width < rectA.x ||
rectA.y + rectA.height < rectB.y ||
rectB.y + rectB.height < rectA.y);
};
cantool.min.js(压缩版):
if(!window.requestAnimationFrame){window.requestAnimationFrame=(window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame||function(callback){return window.setTimeout(callback,17);});}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=(window.cancelRequestAnimationFrame||window.webkitCancelAnimationFrame||window.webkitCancelRequestAnimationFrame||window.mozCancelAnimationFrame||window.mozCancelRequestAnimationFrame||window.msCancelAnimationFrame||window.msCancelRequestAnimationFrame||window.oCancelAnimationFrame||window.oCancelRequestAnimationFrame||window.clearTimeout);}function Ball3d(radius,color){this.x=0;this.y=0;this.xpos=0;this.ypos=0;this.zpos=0;this.vx=0;this.vy=0;this.vz=0;this.radius=radius;this.mass=1;this.rotation=0;this.scaleX=1;this.scaleY=1;this.color=tool.pColor(color);this.lineWidth=1;this.visible=true;}Ball3d.prototype.draw=function(context){context.save();context.translate(this.x,this.y);context.rotate(this.rotation);context.scale(this.scaleX,this.scaleY);context.lineWidth=this.lineWidth;context.fillStyle=this.color;context.beginPath();context.arc(0,0,this.radius,0,(Math.PI*2),true);context.closePath();context.fill();context.stroke();context.restore();};function shipMaker(width,height){this.x=0;this.y=0;this.width=width;this.height=height;this.rotation=0;}shipMaker.prototype.draw=function(context){context.save();context.translate(this.x,this.y);context.rotate(this.rotation);context.lineWidth=1;context.strokeStyle="white";context.beginPath();context.moveTo(10,0);context.lineTo(-10,10);context.lineTo(-5,0);context.lineTo(-10,-10);context.lineTo(10,0);context.stroke();if(this.showFlame){context.beginPath();context.moveTo(-7.5,-5);context.lineTo(-15,0);context.lineTo(-7.5,5);context.stroke();}context.restore();};function Segment(width,height,widthL,color){this.x=0;this.y=0;this.width=width;this.height=height;this.vx=0;this.vy=0;this.rotation=0;this.scaleX=1;this.scaleY=1;this.lineWidth=widthL}Segment.prototype.draw=function(context){var h=this.height;var d=this.width+h;var cr=h/2;context.save();context.translate(this.x,this.y);context.rotate(this.rotation);context.scale(this.scaleX,this.scaleY);context.lineWidth=this.lineWidth;context.beginPath();context.moveTo(0,-cr);context.lineTo(d-h,-cr);context.quadraticCurveTo(-cr+d,-cr,-cr+d,0);context.lineTo(-cr+d,h-2*cr);context.quadraticCurveTo(-cr+d,-cr+h,d-2*cr,-cr+h);context.lineTo(0,-cr+h);context.quadraticCurveTo(-cr,-cr+h,-cr,h-2*cr);context.lineTo(-cr,0);context.quadraticCurveTo(-cr,-cr,0,-cr);context.closePath();context.fill();if(this.lineWidth>0){context.stroke();}};function Slider(min,max,value){this.οnchange=null;this.x=0;this.y=0;this.width=16;this.height=100;this.backWidth=4;this.backX=this.width/2-this.backWidth/2;this.handleHeight=6;this.handleY=0;this.updatePosition();}Slider.prototype.draw=function(context){context.save();context.translate(this.x,this.y);context.beginPath();context.fillRect(this.backX,0,this.backWidth,this.height);context.closePath();context.beginPath();context.rect(0,this.handleY,this.width,this.handleHeight);context.closePath();context.fill();context.stroke();context.restore();};Slider.prototype.updateValue=function(){var old_value=this.value;var handleRange=this.height-this.handleHeight;var valueRange=this.max-this,min;this.value=(handleRange-this.handleY)/handleRange*valueRange+this.min;if(typepf this.οnchange===*function*this.value!==old_value){this.onchage();}};Slider.prototype.updatePosition=function(){var handleRange=this.height-this.handleHeight;var valueRange=this.max-this.min;this.handleY=handleRange-((this.value-this.min)/valueRange)*handleRange;};Slider.prototype.captureMouse=function(element){var self=this;var mouse=utils.captureMouse(element);bounds=[];setHandleBounds();element.addEventListener(*mousedown*,function(){if(utils.containsPoint(bounds,mouse.x,mouse.y)){element.addEventListener(*mouseup*,onMouseUp,false);element.addEventListener(*mousemove*,onMouseMove,false);}},false);function onMouseUp(){element.removeEventListener(*mousemove*,onMouseMove,false);element.removeEventListener(*mouseup*,onMouseMove,false);setHandleBounds();}function onMouseMove(){var pos_y=mouse.y-self.y;self.handleY=Math.min(self.height-self.handleHeight,Math.max(pos_y,0));self.updateValue();}function setHandleBounds(){bounds.x=self.x;bounds.y=self.y+self.handleY;bounds.width=self.width;bounds.height=self.handleHeight;}};function Point3d(x,y,z){this.x=x;this.y=y;this.z=z;this.fl=250;this.vpx=0;this.vpy=0;this.vpz=0;this.cx=0;this.cy=0;this.cz=0;}Point3d.prototype.setVanishingPoint=function(vpx,vpy){this.vpx=vpx;this.vpy=vpy;};Point3d.prototype.setCenter=function(cx,cy,cz){this.cx=cx;this.cy=cy;this.cz=cz;};Point3d.prototype.rorateX=function(angleX){var cosX=Math.cos(angleX);var sinX=Math.sin(angleX);var y1=this.y*cosX-this.z*sinX;var z1=this.z*cosX+this.y*sinX;this.y=y1;this.z=z1;};Point3d.prototype.rotateY=function(angleY){var cosY=Math.cos(angleY);var sinY=Math.sin(angleY);var x1=this.x*cosY-this.z*sinY;var z1=this.z*cosY+this.x*sinY;this.x=x1;this.z=z1;}function Triangle(a,b,c,color){this.pointA=a;this.pointB=b;this.pointC=c;this.color=(color===undefined)?"#ff0000":canTool.strColor(color);this.lineWidth=1;this.alpha=1;}Triangle.prototype.draw=function(context){if(this.isBackface()){return;}context.save();context.lineWidth=this.lineWidth;context.fillStyle=context.strokeStyle=utils.colorToRGB(this.color,this.alpha);context.beginPath();context.moveTo(this.pointA.getScreenX(),this.pointA.getScreenY());context.lineTo(this.pointB.getScreenX(),this.pointB.getScreenY());context.lineTo(this.pointC.getScreenX(),this.pointC.getScreenY());context.closePath();context.fill();if(this.lineWidth>0){context.stroke();}context.restore();};Triangle.prototype.getDepth=function(){return Math.min(this.pointA.z,this.pointB.z,this.pointC.z);};Triangle.prototype.isBackface=function(){var cax=this.pointC.getScreenX()-this.pointA.getScreenX(),cay=this.pointC.getScreenY()-this.pointA.getScreenY(),bcx=this.pointB.getScreenX()-this.pointC.getScreenX(),bcy=this.pointB.getScreenY()-this.pointC.getScreenY();return cax*bcy>cay*bcx;};function lightTriangle(a,b,c,color){this.pointA=a;this.pointB=b;this.pointC=c;this.color=(color===undefined)?"#ff0000":canTool.strColor(color);this.lineWidth=1;this.alpha=1;this.light=null;}lightTriangle.prototype.draw=function(context){if(this.isBackface()){return;}context.save();context.lineWidth=this.lineWidth;context.fillStyle=context.strokeStyle=this.getAdjustedColor();context.beginPath();context.moveTo(this.pointA.getScreenX(),this.pointA.getScreenY());context.lineTo(this.pointB.getScreenX(),this.pointB.getScreenY());context.lineTo(this.pointC.getScreenX(),this.pointC.getScreenY());context.closePath();context.fill();if(this.lineWidth>0){context.stroke();}context.restore();};lightTriangle.prototype.getDepth=function(){return Math.min(this.pointA.z,this.pointB.z,this.pointC.z);};lightTriangle.prototype.isBackface=function(){var cax=this.pointC.getScreenX()-this.pointA.getScreenX(),cay=this.pointC.getScreenY()-this.pointA.getScreenY(),bcx=this.pointB.getScreenX()-this.pointC.getScreenX(),bcy=this.pointB.getScreenY()-this.pointC.getScreenY();return cax*bcy>cay*bcx;};lightTriangle.prototype.getAdjustedColor=function(){var color=utils.parseColor(this.color,true),red=color>>16,green=color>>8&0xff,blue=color&0xff,lightFactor=this.getLightFactor();red*=lightFactor;green*=lightFactor;blue*=lightFactor;return utils.parseColor(red<<16|green<<8|blue);};lightTriangle.prototype.getLightFactor=function(){var ab={x:this.pointA.x-this.pointB.x,y:this.pointA.y-this.pointB.y,z:this.pointA.z-this.pointB.z};var bc={x:this.pointB.x-this.pointC.x,y:this.pointB.y-this.pointC.y,z:this.pointB.z-this.pointC.z};var norm={x:(ab.y*bc.z)-(ab.z*bc.y),y:-((ab.x*bc.z)-(ab.z*bc.x)),z:(ab.x*bc.y)-(ab.y*bc.x)};var dotProd=norm.x*this.light.x+norm.y*this.light.y+norm.z*this.light.z,normMag=Math.sqrt(norm.x*norm.x+norm.y*norm.y+norm.z*norm.z),lightMag=Math.sqrt(this.light.x*this.light.x+this.light.y*this.light.y+this.light.z*this.light.z);return(Math.acos(dotProd/(normMag*lightMag))/Math.PI)*this.light.brightness;};function Light(x,y,z,brightness){this.x=(x===undefined)?-100:x;this.y=(y===undefined)?-100:y;this.z=(z===undefined)?-100:z;this.brightness=(brightness===undefined)?1:brightness;}Light.prototype.setBrightness=function(b){this.brightness=Math.min(Math.max(b,0),1);};var canTool={};window.canTool.strColor=function(color,toNumber){if(toNumber===true){if(typeof color===*number*){return(color|0);}if(typeof color===*string*&&color[0]===*#*){color=color.slice(1);}return window.parseInt(color,16);}else{if(typeof color===*number*){color=*#*+(*00000*+(color|0).toString(16)).substr(-6);}return color;}};window.canTool.getMousePos=function(element){var mouse={x:0,y:0,event:null},body_scrollLeft=document.body.scrollLeft,element_scrollLeft=document.documentElement.scrollLeft,body_scrollTop=document.body.scrollTop,element_scrollTop=document.documentElement.scrollTop,offsetLeft=element.offsetLeft,offsetTop=element.offsetTop;element.addEventListener(*mousemove*,function(event){var x,y;if(event.pageX||event.pageY){x=event.pageX;y=event.pageY;}else{x=event.clientX+body_scrollLeft+element_scrollLeft;y=event.clientY+body_scrollTop+element_scrollTop;}x-=offsetLeft;y-=offsetTop;mouse.x=x;mouse.y=y;mouse.event=event;},false);return mouse;};window.canTool.getTouchPos=function(element){var touch={x:null,y:null,isPressed:false,event:null},body_scrollLeft=document.body.scrollLeft,element_scrollLeft=document.documentElement.scrollLeft,body_scrollTop=document.body.scrollTop,element_scrollTop=document.documentElement.scrollTop,offsetLeft=element.offsetLeft,offsetTop=element.offsetTop;element.addEventListener(*touchstart*,function(event){touch.isPressed=true;touch.event=event;},false);element.addEventListener(*touchend*,function(event){touch.isPressed=false;touch.x=null;touch.y=null;touch.event=event;},false);element.addEventListener(*touchmove*,function(event){var x,y,touch_event=event.touches[0];if(touch_event.pageX||touch_event.pageY){x=touch_event.pageX;y=touch_event.pageY;}else{x=touch_event.clientX+body_scrollLeft+element_scrollLeft;y=touch_event.clientY+body_scrollTop+element_scrollTop;}x-=offsetLeft;y-=offsetTop;touch.x=x;touch.y=y;touch.event=event;},false);return touch;};window.canTool.colorToRGB=function(color,alpha){if(typeof color===*string*&&color[0]===*#*){color=window.parseInt(color.slice(1),16);}alpha=(alpha===undefined)?1:alpha;var r=color>>16&0xff,g=color>>8&0xff,b=color&0xff,a=(alpha<0)?0:((alpha>1)?1:alpha);if(a===1){return"rgb("+r+","+g+","+b+")";}else{return"rgba("+r+","+g+","+b+","+a+")";}};window.canTool.containsPoint=function(rect,x,y){return!(xrect.x+rect.width||yrect.y+rect.height);};window.canTool.intersects=function(rectA,rectB){return!(rectA.x+rectA.width