자바 스크립트에서 손으로 다트 데모 중 하나를 쓰려고합니다. firebug와 비슷한 크롬을 사용하여 SolarSystem
클래스의 draw
함수에서 발생하는 이상한 TypeError: this.canvas is undefined
오류가 발생합니다. 왜 이런 일이 일어나는지 알 수 없습니다.TypeError : this.canvas가 정의되지 않았습니다.
여기 JS Bin의 코드에 대한 링크가 있으므로 함께 놀 수 있습니다. http://jsbin.com/udujep/1/edit
후세를 들어, 다음은 전체 자바 스크립트 코드입니다 :
var main, fpsAverage, showFps, Point, SolarSystem, PlanetaryBody;
main = function(){
var solarSystem;
solarSystem = new SolarSystem(document.getElementById('container'));
solarSystem.start();
};
showFps = function(fps){
if (fpsAverage != null) {
fpsAverage = fps;
}
fpsAverage = fps * 0.05 + fpsAverage * 0.95;
document.getElementById('notes').textContent = Math.round(fpsAverage) + ' fps';
};
Point = (function(){
Point.displayName = 'Point';
var prototype = Point.prototype, constructor = Point;
function Point(x, y){
var ref$;
ref$ = [x, y], this.x = ref$[0], this.y = ref$[1];
}
return Point;
}());
SolarSystem = (function(){
SolarSystem.displayName = 'SolarSystem';
var prototype = SolarSystem.prototype, constructor = SolarSystem;
prototype.canvas = null;
prototype.renderTime = null;
function SolarSystem(canvas){
this.canvas = canvas;
}
prototype.start = function(){
this.width = this.canvas.parentNode.clientWidth;
this.height = this.canvas.parentNode.clientWidth;
this.canvas.width = this.width;
this._start();
};
prototype._start = function(){
var earth, f, h, g, jupiter;
this.sun = new PlanetaryBody(this, 'Sun', '#ff2', 14.0);
this.sun.addPlanet(new PlanetaryBody(this, 'Mercury', 'orange', 0.382, 0.387, 0.241));
this.sun.addPlanet(new PlanetaryBody(this, 'Venus', 'green', 0.949, 0.723, 0.615));
earth = new PlanetaryBody(this, 'Earth', '#33f', 1.0, 1.0, 1.0);
this.sun.addPlanet(earth);
earth.addPlanet(new PlanetaryBody(this, 'Moon', 'gray', 0.2, 0.14, 0.075));
this.sun.addPlanet(new PlanetaryBody(this, 'Mars', 'red', 0.532, 1.524, 1.88));
this.addAsteroidBelt(this.sun, 150);
f = 0.1;
h = 1/1500.0;
g = 1/72.0;
jupiter = new PlanetaryBody(this, 'Jupiter', 'gray', 4.0, 5.203, 11.86);
this.sun.addPlanet(jupiter);
jupiter.addPlanet(new PlanetaryBody(this, 'Io', 'gray', 3.6 * f, 421 * h, 1.769 * g));
jupiter.addPlanet(new PlanetaryBody(this, 'Europa', 'gray', 3.1 * f, 671 * h, 3.551 * g));
jupiter.addPlanet(new PlanetaryBody(this, 'Ganymede', 'gray', 5.3 * f, 1070 * h, 7.154 * g));
jupiter.addPlanet(new PlanetaryBody(this, 'Callisto', 'gray', 4.8 * f, 1882 * h, 16.689 * g));
this.requestRedraw();
};
prototype.draw = function(){
var time, context;
time = Date.now();
if (this.renderTime != null) {
showFps(Math.round(1000/(time - this.renderTime)));
}
this.renderTime = time;
context = this.canvas.getContext('2d');
this.drawBackground(context);
this.drawPlanets(context);
this.requestRedraw();
};
prototype.drawBackground = function(context){
var x$;
x$ = context;
x$.fillStyle = 'white';
x$.rect(0, 0, this.width, this.height);
x$.fill();
};
prototype.drawPlanets = function(context){
this.sun.draw(context, this.width/2, this.height/2);
};
prototype.requestRedraw = function(){
window.requestAnimationFrame(this.draw);
};
prototype.addAsteroidBelt = function(body, count){
var i$, radius;
for (i$ = 0; i$ < count; ++i$) {
radius = 2.06 + Math.random() * (3.27 - 2.06);
body.addPlanet(new PlanetaryBody(this, 'asteroid', '#777', 0.1 * Math.random(), radius, radius * 2));
}
};
prototype.normalizeOrbitRadius = function(r){
return r * (this.width/10.0);
};
prototype.normalizePlanetSize = function(r){
return Math.log(r + 1) * (this.width/100.0);
};
return SolarSystem;
}());
PlanetaryBody = (function(){
PlanetaryBody.displayName = 'PlanetaryBody';
var prototype = PlanetaryBody.prototype, constructor = PlanetaryBody;
prototype.planets = [];
function PlanetaryBody(solarSystem, name, color, bodySize, orbitRadius, orbitPeriod){
orbitRadius == null && (orbitRadius = 0.0);
orbitPeriod == null && (orbitPeriod = 0.0);
this.solarSystem = solarSystem;
this.name = name;
this.color = color;
this.orbitPeriod = orbitPeriod;
this.bodySize = solarSystem.normalizePlanetSize(bodySize);
this.orbitRadius = solarSystem.normalizeOrbitRadius(orbitRadius);
this.orbitSpeed = prototype._calculateSpeed(orbitPeriod);
}
prototype.addPlanet = function(planet){
this.planets.push(planet);
};
prototype.draw = function(context, x, y){
var pos;
pos = this._calculatePos(x, y);
this.drawSelf(context, pos.x, pos.y);
this.drawChildren(context, pos.x, pos.y);
};
prototype.drawSelf = function(context, x, y){
var x$;
x$ = context;
x$.save();
try {
x$.lineWidth = 0.5;
x$.fillStyle = this.color;
x$.strokeStyle = this.color;
if (this.bodySize >= 2.0) {
x$.shadowOffsetX = 2;
x$.shadowOffsetY = 2;
x$.shadowBlur = 2;
x$.shadowColor = '#ddd';
}
x$.beginPath();
x$.arc(x, y, this.bodySize, 0, Math.PI * 2, false);
x$.fill();
x$.closePath();
x$.stroke();
x$.shadowOffsetX = 0;
x$.shadowOffsetY = 0;
x$.shadowBlur = 0;
x$.beginPath();
x$.arc(x, y, this.bodySize, 0, Math.PI * 2, false);
x$.fill();
x$.closePath();
x$.stroke();
} finally {
x$.restore();
}
};
prototype.drawChildren = function(context, x, y){
var i$, ref$, len$, planet;
for (i$ = 0, len$ = (ref$ = this.planets).length; i$ < len$; ++i$) {
planet = ref$[i$];
planet.draw(context, x, y);
}
};
prototype._calculateSpeed = function(period){
if (period === 0.0) {
return 0.0;
} else {
return 1/(60.0 * 24.0 * 2 * period);
}
};
prototype._calculatePos = function(x, y){
var angle;
if (this.orbitSpeed === 0.0) {
return new Point(x, y);
} else {
angle = this.solarSystem.renderTime * this.orbitSpeed;
return new Point(this.orbitRadius * Math.cos(angle) + x, this.orbitRadius * Math.sin(angle) + y);
}
};
return PlanetaryBody;
}());
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.onload = main;