我试图在Javascript / Coffeescript中编写其中一个Dart演示。就代码而言,一切似乎都很好,但画布上没有任何东西出现过。我已经在Firefox和Chrome中对此进行了测试,但我没有收到任何控制台错误或其他任何错误。我无法想象这一个。我的画布留空的任何想法?
这是我在http://jsbin.com/orazag/1/edit
的代码对于子孙后代,这里也是如此。
HTML:
<!DOCTYPE html>
<!-- Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
for details. All rights reserved. Use of this source code is governed by a
BSD-style license that can be found in the LICENSE file. -->
<html>
<head>
<meta charset="utf-8">
<title>Solar System Demo</title>
<link type="text/css" rel="stylesheet" href="solar.css">
</head>
<body>
<h1>Solar System</h1>
<p>A solar system visualization using requestAnimationFrame.</p>
<div>
<canvas id="container" width="500px" height="400px"></canvas>
</div>
<footer>
<p id="summary"> </p>
<p id="notes"> </p>
</footer>
<script type="text/javascript" src="solar.js"></script>
</body>
</html>
CSS:
/* Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file */
/* for details. All rights reserved. Use of this source code is governed by a */
/* BSD-style license that can be found in the LICENSE file. */
body {
background-color: #F8F8F8;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
font-weight: normal;
line-height: 1.2em;
margin: 15px;
}
p {
color: #333;
}
#container {
border: 1px solid #ccc;
background-color: #fff;
}
#summary {
float: left;
}
#notes {
float: right;
width: 120px;
text-align: right;
}
.error {
font-style: italic;
color: red;
}
CoffeeScript的:
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
main = ->
solarSystem = new SolarSystem document.getElementById 'container'
solarSystem.start()
return
fpsAverage = null
showFps = (fps) ->
fpsAverage ?= fps
fpsAverage = fps * 0.05 + fpsAverage * 0.95
document.getElementById('notes').textContent = Math.round(fpsAverage) + ' fps'
return
class Point
constructor: (@x, @y) ->
class SolarSystem
constructor: (@canvas) ->
@renderTime = null
start: ->
@width = @canvas.parentNode.clientWidth
@height = @canvas.parentNode.clientHeight
@canvas.width = @width
@_start()
return
_start: ->
# Create the Sun.
@sun = new PlanetaryBody @, 'Sun', '#ff2', 14.0
# Add planets.
@sun.addPlanet new PlanetaryBody @, 'Mercury', 'orange', 0.382, 0.387, 0.241
@sun.addPlanet new PlanetaryBody @, 'Venus', 'green', 0.949, 0.723, 0.615
earth = new PlanetaryBody @, 'Earth', '#33f', 1.0, 1.0, 1.0
@sun.addPlanet earth
earth.addPlanet new PlanetaryBody @, 'Moon', 'gray', 0.2, 0.14, 0.075
@sun.addPlanet new PlanetaryBody @, 'Mars', 'red', 0.532, 1.524, 1.88
@addAsteroidBelt @sun, 150
f = 0.1
h = 1 / 1500.0
g = 1 / 72.0
jupiter = new PlanetaryBody @, 'Jupiter', 'gray', 4.0, 5.203, 11.86
@sun.addPlanet jupiter
jupiter.addPlanet new PlanetaryBody @, 'Io', 'gray', 3.6 * f, 421 * h, 1.769 * g
jupiter.addPlanet new PlanetaryBody @, 'Europa', 'gray', 3.1 * f, 671 * h, 3.551 * g
jupiter.addPlanet new PlanetaryBody @, 'Ganymede', 'gray', 5.3 * f, 1070 * h, 7.154 * g
jupiter.addPlanet new PlanetaryBody @, 'Callisto', 'gray', 4.8 * f, 1882 * h, 16.689 * g
@requestRedraw()
return
draw: ->
@requestRedraw()
time = Date.now()
if @renderTime?
showFps Math.round 1000 / (time - @renderTime)
@renderTime = time
context = @canvas.getContext '2d'
@drawBackground context
@drawPlanets context
return
drawBackground: (context) ->
context.fillStyle = 'white'
context.rect 0, 0, @width, @height
context.fill()
return
drawPlanets: (context) ->
@sun.draw context, @width / 2, @height /2
return
requestRedraw: ->
window.requestAnimationFrame => @draw()
return
addAsteroidBelt: (body, count) ->
# Asteroids are generally between 2.06 and 3.27 AUs.
for [0...count]
radius = 2.06 + Math.random() * (3.27 - 2.06)
body.addPlanet new PlanetaryBody @, 'asteroid', '#777', 0.1 * Math.random(), radius, radius * 2
return
normalizeOrbitRadius: (r) ->
r * (@width / 10.0)
normalizePlanetSize: (r) ->
Math.log(r + 1) * (@width / 100.0)
class PlanetaryBody
constructor: (@solarSystem, @name, @color, bodySize, orbitRadius = 0.0, @orbitPeriod = 0.0) ->
@bodySize = solarSystem.normalizePlanetSize bodySize
@orbitRadius = solarSystem.normalizeOrbitRadius orbitRadius
@orbitSpeed = @_calculateSpeed orbitPeriod
@planets = []
addPlanet: (planet) ->
@planets.push planet
draw: (context, x, y) ->
pos = @_calculatePos x, y
@drawSelf context, pos.x, pos.y
@drawChildren context, pos.x, pos.y
return
drawSelf: (context, x, y) ->
context.save()
try
context.lineWidth = 0.5
context.fillStyle = @color
context.strokeStyle = @color
if @bodySize >= 2.0
context.shadowOffsetX = 2
context.shadowOffsetY = 2
context.shadowBlur = 2
context.shadowColor = '#ddd'
context.beginPath()
context.arc x, y, @bodySize, 0, Math.PI * 2, false
context.fill()
context.closePath()
context.stroke()
context.shadowOffsetX = 0
context.shadowOffsetY = 0
context.shadowBlur = 0
context.beginPath()
context.arc x, y, @bodySize, 0, Math.PI * 2, false
context.fill()
context.closePath()
context.stroke()
finally
context.restore()
return
drawChildren: (context, x, y) ->
for planet in @planets
planet.draw context, x, y
return
_calculateSpeed: (period) ->
if period == 0.0
0.0
else
1 / (60.0 * 24.0 * 2 * period)
_calculatePos: (x, y) ->
if @orbitSpeed == 0.0
new Point x, y
else
angle = @solarSystem.renderTime * @orbitSpeed
new Point @orbitRadius * Math.cos(angle) + x, @orbitRadius * Math.sin(angle) + y
window.onload = main
或者,如果您愿意,可以使用等效的Javascript:
// Generated by CoffeeScript 1.4.0
(function() {
var PlanetaryBody, Point, SolarSystem, fpsAverage, main, showFps;
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
main = function() {
var solarSystem;
solarSystem = new SolarSystem(document.getElementById('container'));
solarSystem.start();
};
fpsAverage = null;
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() {
function Point(x, y) {
this.x = x;
this.y = y;
}
return Point;
})();
SolarSystem = (function() {
function SolarSystem(canvas) {
this.canvas = canvas;
this.renderTime = null;
}
SolarSystem.prototype.start = function() {
this.width = this.canvas.parentNode.clientWidth;
this.height = this.canvas.parentNode.clientHeight;
this.canvas.width = this.width;
this._start();
};
SolarSystem.prototype._start = function() {
var earth, f, g, h, 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();
};
SolarSystem.prototype.draw = function() {
var context, time;
this.requestRedraw();
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);
};
SolarSystem.prototype.drawBackground = function(context) {
context.fillStyle = 'white';
context.rect(0, 0, this.width, this.height);
context.fill();
};
SolarSystem.prototype.drawPlanets = function(context) {
this.sun.draw(context, this.width / 2, this.height / 2);
};
SolarSystem.prototype.requestRedraw = function() {
var _this = this;
window.requestAnimationFrame(function() {
return _this.draw();
});
};
SolarSystem.prototype.addAsteroidBelt = function(body, count) {
var radius, _i;
for (_i = 0; 0 <= count ? _i < count : _i > count; 0 <= count ? _i++ : _i--) {
radius = 2.06 + Math.random() * (3.27 - 2.06);
body.addPlanet(new PlanetaryBody(this, 'asteroid', '#777', 0.1 * Math.random(), radius, radius * 2));
}
};
SolarSystem.prototype.normalizeOrbitRadius = function(r) {
return r * (this.width / 10.0);
};
SolarSystem.prototype.normalizePlanetSize = function(r) {
return Math.log(r + 1) * (this.width / 100.0);
};
return SolarSystem;
})();
PlanetaryBody = (function() {
function PlanetaryBody(solarSystem, name, color, bodySize, orbitRadius, orbitPeriod) {
this.solarSystem = solarSystem;
this.name = name;
this.color = color;
if (orbitRadius == null) {
orbitRadius = 0.0;
}
this.orbitPeriod = orbitPeriod != null ? orbitPeriod : 0.0;
this.bodySize = solarSystem.normalizePlanetSize(bodySize);
this.orbitRadius = solarSystem.normalizeOrbitRadius(orbitRadius);
this.orbitSpeed = this._calculateSpeed(orbitPeriod);
this.planets = [];
}
PlanetaryBody.prototype.addPlanet = function(planet) {
return this.planets.push(planet);
};
PlanetaryBody.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);
};
PlanetaryBody.prototype.drawSelf = function(context, x, y) {
context.save();
try {
context.lineWidth = 0.5;
context.fillStyle = this.color;
context.strokeStyle = this.color;
if (this.bodySize >= 2.0) {
context.shadowOffsetX = 2;
context.shadowOffsetY = 2;
context.shadowBlur = 2;
context.shadowColor = '#ddd';
}
context.beginPath();
context.arc(x, y, this.bodySize, 0, Math.PI * 2, false);
context.fill();
context.closePath();
context.stroke();
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowBlur = 0;
context.beginPath();
context.arc(x, y, this.bodySize, 0, Math.PI * 2, false);
context.fill();
context.closePath();
context.stroke();
} finally {
context.restore();
}
};
PlanetaryBody.prototype.drawChildren = function(context, x, y) {
var planet, _i, _len, _ref;
_ref = this.planets;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
planet = _ref[_i];
planet.draw(context, x, y);
}
};
PlanetaryBody.prototype._calculateSpeed = function(period) {
if (period === 0.0) {
return 0.0;
} else {
return 1 / (60.0 * 24.0 * 2 * period);
}
};
PlanetaryBody.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.onload = main;
}).call(this);
答案 0 :(得分:3)
我的基本调试过程是:
console.log('drawing')
告诉我,是的。console.log(x, y)
告诉我两者都是NaN
。因此,在我周围散布了一些console.log
时,我发现发送到绘图函数的X和Y是NaN
。所以某处你做了一些糟糕的数学运算。我将其追溯到您传入_calculateSpeed
的构造函数中的orbitPeriod
方法,但构造接受为@orbitPeriod
,这当然是完全不同的事情。
class PlanetaryBody
constructor: (@solarSystem, @name, @color, bodySize, orbitRadius = 0.0, @orbitPeriod = 0.0) ->
@bodySize = solarSystem.normalizePlanetSize bodySize
@orbitRadius = solarSystem.normalizeOrbitRadius orbitRadius
# This line right here:
@orbitSpeed = @_calculateSpeed orbitPeriod
# Should be this instead!
@orbitSpeed = @_calculateSpeed @orbitPeriod
@planets = []
console.log
是您的朋友,将其添加到您认为数据混乱到专业人员调试的位置。