I'm trying to implement the Creating a scene example for three.js in clojurescript.
I'm not doing the animation and just want to display the static scene (a green block).
The problem appears to be in this function that is called to render the scene.
(defn ^:export draw []
(.render renderer scene camera)
)
This is what is doing the calling from the HTML.
%script{:type => "text/javascript"}
three.demo.draw();
It sees and runs the draw function, for example, when I have it print out "HELLO" to the body of the document.
(.write js/document "HELLO")
I have no idea what's wrong, everything else on the page is rendered.
In this HTML file, I have
<script src='https://raw.github.com/mrdoob/three.js/master/build/three.js'></script>
<script src='js/main.js' type='text/javascript'></script>
<script type='text/javascript'>goog.require('main')</script>
and
<script type='text/javascript'>
three.demo.draw();
</script>
Below is the end of main.js, which is the Javascript created from the clojurescript file.
goog.provide("three.demo");
goog.require("cljs.core");
goog.require("goog.dom");
three.demo.scene = new THREE.Scene;
three.demo.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1E3);
three.demo.renderer = new THREE.WebGLRenderer;
three.demo.renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(three.demo.renderer.domElement);
three.demo.geometry = new THREE.CubeGeometry(1, 1, 1);
three.demo.material = new THREE.MeshBasicMaterial(cljs.core.ObjMap.fromObject(["\ufdd0'color"], {"\ufdd0'color":255}));
three.demo.cube = new THREE.Mesh(three.demo.geometry, three.demo.material);
three.demo.scene.add(three.demo.cube);
three.demo.camera.position.setZ(5);
three.demo.draw = function draw() {
three.demo.renderer.render(three.demo.scene, three.demo.camera);
return document.write("HELLO")
};
goog.exportSymbol("three.demo.draw", three.demo.draw);
Under :cljsbuild in the project.clj file has
:foreign-libs [{:file "https://raw.github.com/mrdoob/three.js/master/build/three.js"
:provides ["three"]}]
I tried :externs and :foreign-libs and neither seems to work.
The direct translation of the Creating a scene code would be:
(defn ^:export example []
(let [scene (js/THREE.Scene.)
width (.-innerWidth js/window)
height (.-innerHeight js/window)
camera (js/THREE.PerspectiveCamera. 75 (/ width height) 0.1 1000 )
renderer (js/THREE.CanvasRenderer.)
geometry (js/THREE.CubeGeometry. 1 1 1)
material (js/THREE.MeshBasicMaterial. (clj->js {:color 0x00ff00}))
cube (js/THREE.Mesh. geometry material)
render (fn cb []
(js/requestAnimationFrame cb)
(set! (.-x (.-rotation cube)) (+ 0.1 (.-x (.-rotation cube))) )
(set! (.-y (.-rotation cube)) (+ 0.1 (.-y (.-rotation cube))) )
(.render renderer scene camera)
)
]
(.setSize renderer width height)
(.appendChild js/document.body (.-domElement renderer) )
(.add scene cube)
(set! (.-z (.-position camera)) 5)
(render)
)
)
This is not using :foreign-libs
and :require
; it uses the direct JS interop and assumes that three.js was previously loaded. It can be probably done in a nicer way, but this is a one-to-one translation that works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With