Jump to content
gbball

Using a js game engine is there a way to put the script in a database so that different pages can run unique interactive canvases?

Recommended Posts

Hopefully this is the right place to ask this question, if not, please direct me to a better place.

I've been trying for a few weeks to figure this out and I keep getting blocked by one thing or another.

 

What I'm trying to do is use Bablyon.js, the html5 game engine to create a 3d interactive comic on my processwire site.

What I was hoping to achieve is something where I could have a template file called  comic-post.php that has a canvas element in it where the 3d scene would load. 

<canvas id="renderCanvas"></canvas>

Then in the template add a Unknown/Text field called js that would contain the javascript.  Also in the comic-post.php file, I also would have the following.

<script>
  <?php $page->js ?>
</script>

And the script, which I would input through the js field I created looks like this.

	//get canvas element from the page by it's id
	var canvas = document.getElementById("renderCanvas");

	var createScene = function () {
	var scene = new BABYLON.Scene(engine);

	//Adding a light
	var light = new BABYLON.HemisphericLight();

	//Adding an Arc Rotate Camera
	var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 10, BABYLON.Vector3.Zero(), scene);
	camera.attachControl(canvas, false);

	// The first parameter can be used to specify which mesh to import. Here we import all meshes
	BABYLON.SceneLoader.Append("<?php urls()->templates?>babylon/glb", "Silo.glb", scene, function (newMeshes) {
		scene.activeCamera = null;
		scene.createDefaultCameraOrLight(true);
		scene.activeCamera.attachControl(canvas, false);
	});

	return scene;
};

var engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
var scene = createScene();

engine.runRenderLoop(function () {
	if (scene) {
		scene.render();
	}
});

// Resize
window.addEventListener("resize", function () {
	engine.resize();
});

This line below is looking for a glTF file called Silo.glb in my templates directory under babylon/glb

BABYLON.SceneLoader.Append("<?php urls()->templates?>babylon/glb", "Silo.glb", scene, function (newMeshes)

I'm working with the uikit blog template and I'm using the blog-post.php template as a basis.  I've also added a _uikit-comic.php file that loads after _init.php and _uikit.php. 

So after doing all this, I can't seem to get it working the way I want and the javascript won't load it seems.  The canvas is there, but it is blank.

I can get it to work properly if I put the javascript directly into the comic-post.php directly, but then I have the problem of not being able to reuse the template for different scenes.

Is there a certain way I need to set up the parameters for the textarea field in order for the page to load and run the javascript correctly, or is this something that is not possible?

Thanks!

-G

 

Share this post


Link to post
Share on other sites
Posted (edited)
2 hours ago, gbball said:

Then in the template add a Unknown/Text field called js that would contain the javascript. 

I don't think this is good design. You can do it, but there are better ways. 

Do your different scenes have different scripts or just different variables but using the same script? If the latter, what you can do is store the unique properties of the scenes in the text field. A common approach is to use JSON with key:value pairs. You would then pass those to your script. There are two approaches to pass the data to your script; using $config->js() or echo'ing the JS variable in your template file. Please see these threads for more details:

 

If you scenes have completely different scripts, you can either handle that in your JS code, if this scene then this, if that scene then that. Alternatively, you can have one template for all scenes that includes different other files based on the scene.

 

 

Edited by kongondo
  • Like 2

Share this post


Link to post
Share on other sites

Yeah, really easy. I'd write your own implementation:

<?php
$js = (object)[
  'foo' => 'bar',
];
?>

<script>
mySettings = <?= json_encode($js) ?>;
var yourLibrary = new yourLibrary();

yourLibrary.setWhatever(mySettings.foo); // mySettings.foo = bar
</script>

Escaping might be a problem sometimes. Just see how $config->js() does it; I think it would be nice to have such a feature built into ProcessWire - but a JS API is on the roadmap for a long time...

Share this post


Link to post
Share on other sites

Thanks @kongondo 

I'm willing to approach it either way, but there will be case where the script is vastly different in which case I think it would be more flexible if I could just substitute the entire block of Babylon code to suit different situations. 

and @bernhard, I will take a look at this as well, but where would this code live?  In my template file?

To both of you, when you say to use $config->js() is that referring to the field that I created on my template called js or is there something else already in processwire with the same name that you're referring to?

I'm relatively inexperienced with anything more than basic web development, but I have a decent grasp of coding concepts and good enough javascript abilities to get by.  I have very little experience with php, but I'm willing to learn.  I've heard of json before, but never used it.  You've both given me a lot to investigate.

Also, can you recommend documentation on this site to look at best practices with regards to what I want to do, or is modular javascript cumbersome at this point?  Would it be a good idea to make a module or use a hook for example?  Or should I just handle everything in the template file.  And is json just like a kind of data type or variable?  Does it need to be a separate file?  Or is it like javascript in the sense that it can be embedded into a file or handled as a separate file?  I'm sure it will come up as I do more research, but it's always faster to ask people who know.

Thanks again.  I greatly appreciate the help!

 

Share this post


Link to post
Share on other sites

you could just store it in a single textarea field and use the AceExtended inputfield. You can just paste that whole block of code into your field, stored in database, and have nice JS syntax highlighting.

Share this post


Link to post
Share on other sites

Hi @gbball,

that's similar questions I asked when I shared my first project here in the forum, which was also a webapp with lots of mixed javascript + php involved. And I also stored lots of JavaScript in textarea fields: 

The project is dead, but you might still find some interesting code snippets in it - even though I would do everything completely different now 😄 

Back to your questions:

1) What is JSON? https://en.wikipedia.org/wiki/JSON

10 hours ago, gbball said:

Would it be a good idea to make a module or use a hook for example?

Modules are always the way to go when you want/need to reuse or share your code at some time. It's easier to just start writing code in the templates, but it's a lot more flexible, powerful and robust when you start writing modules and to understand OOP concepts of PHP. Which road you want to take depends on you, on the project, on the deadlines... If you want to start quick, just go ahead, get something done, have fun, hit some walls, learn, improve 🙂 

To my code example: Just take this in your home.php file to get the idea.

<?php
$js = (object)[
  'page' => [
    'id' => $page->id,
    'path' => $page->path,
    'name' => $page->name,
    'title' => $page->title,
  ],
  'foo' => 'bar',
];
?>

<script>
mySettings = <?= json_encode($js) ?>;
console.log(mySettings);
</script>

0uYtYch.png

That way you can communicate between PHP and JS without mixing both languages in one file too much. Of course you assign the PHP $js settings to mySettings JS variable once, but then you can just access those variables from within JS. You could then include a regular JS file that shows your animations... checking for specific variables and values and then changing its look or features based on the value of those variables.

  • Like 3

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...