       :fill (do (aset context "fillStyle" color)
                 (.fillRect context x0 y0 (- x1 x0) (- y1 y0))))))
 
+(defn enclosing-rectangle
+  "Calculates an enclosing rectangle which contains the given
+  one centered on the screen (would you believe that working
+  this out was the hardest thing in this project?)"
+  [x0 y0 width height screen-width screen-height]
+  (let [portrait?    (>= height width)
+
+        aspect-ratio (/ width height)
+
+        padding      (if portrait?
+                       (- screen-width (* screen-height aspect-ratio))
+                       (- screen-height (/ screen-width aspect-ratio)))
+
+        scale        (if portrait?
+                       (/ screen-height height)
+                       (/ screen-width width))]
+
+    (if portrait?
+      {:x0     (- x0 (* 0.5 (/ padding scale)))
+       :y0     y0
+       :width  (+ width (/ padding scale))
+       :height height
+       :scale  scale}
+
+      {:x0     x0
+       :y0     (+ y0 (* 0.5 (/ padding scale)))
+       :width  width
+       :height (+ height (/ padding scale))
+       :scale  scale})))
+
 (defn render-mandelbrot!
   "Iterate over every pixel in the canvas, rendering the mandelbrot
   set at the specified scale. Uses a javascript function (in resources/public/js/fractal-maths.js)
   for the hard maths, because clojurescript just wasn't cutting it speed wise (you really want local
   variables for this kind of thing - I got it to be only ~10 times slower using the >> and << macros)"
   [{:keys [canvas overlay-canvas escape-radius]
-    {:keys [scale x0 y0] :as render-state} :rendering-data}]
+    {:keys [width height x0 y0] :as render-state} :rendering-data}]
+
+  (println render-state)
 
   (set-canvas-dimensions! canvas)
   (set-canvas-dimensions! overlay-canvas)
   (clear-canvas! overlay-canvas)
 
-  (let [context               (.getContext canvas "2d")
-        max-iterations        (int (* 10 (Math/log scale))) ; Sensible?
-        start                 (.getTime (js/Date.))
-
-        width                 (.-width canvas)
-        height                (.-height canvas)
-        idata                 (.createImageData context width height)
-        data                  (.-data idata)
-
-        escape-radius-squared (* escape-radius escape-radius)]
+  (let [screen-width             (.-width canvas)
+        screen-height            (.-height canvas)
+        {:keys [x0 y0 scale]
+         :as rendered-rectangle} (enclosing-rectangle x0 y0 width height screen-width screen-height)
+
+        context                  (.getContext canvas "2d")
+        max-iterations           (int (* 10 (Math/log scale))) ; Sensible?
+        start                    (.getTime (js/Date.))
+
+
+        idata                    (.createImageData context screen-width screen-height)
+        data                     (.-data idata)
+
+        escape-radius-squared    (* escape-radius escape-radius)]
+
+    (println rendered-rectangle)
+    (swap! app-state assoc :rendered-rectangle rendered-rectangle)
 
     (forloop
-     [(x 0) (< x width)  (inc x)]
+     [(x 0) (< x screen-width)  (inc x)]
      (forloop
-      [(y 0) (< y height) (inc y)]
+      [(y 0) (< y screen-height) (inc y)]
 
       (let [real       (+ (/ x scale) x0)
             imaginary  (- (/ y scale) y0)
             iterations (js/mandelbrot_smoothed_iteration_count escape-radius-squared max-iterations real imaginary)
             intensity  (* 255 (/ iterations max-iterations))
-            data-index (* 4 (+ x (* y width)))]
+            data-index (* 4 (+ x (* y screen-width)))]
 
         (aset data data-index intensity)
         (aset data (+ data-index 1) intensity)

(enable-console-print!)

(def initial-rendering-data
  {:scale          (/ (.-innerWidth js/window) 4) ; How many pixels a distance of 1 in the complex plane takes up
   :x0             -3 ; the x co-ordinate of the top-left pixel in the canvase
   :y0             1.2 ; the y co-ordinate of the top-left pixel in the canvase
   })

(defonce app-state (atom {:canvas         (.getElementById js/document "canvas")


    (.putImageData context idata 0 0)

    (.log js/console "Done in: " (int (* 1000 (/ (* screen-height screen-width)
                                                 (- (.getTime (js/Date.)) start)))) "px/s")))

(defn re-render!
  "Adds a green semi-transparent overlay to the screen, then
