2012-11-10 118 views
1

我試圖在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); 

回答

3

我的基本調試過程如下:

  1. 是否調用繪圖函數? console.log('drawing')在繪圖功能告訴我,是的,他們是。
  2. 繪圖函數是否發送正確的值? 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是你的朋友,加它,你認爲你的數據被搞砸調試像親。

+0

感謝您的補充信息。另外,多麼尷尬!它歸結爲單個字符錯字。 – DynamiteReed

+0

在我遇到一些最令人困惑的,多產的錯誤時,測試你的理智通常會變得微不足道。不要對自己太難。 :) –

相關問題