Canvas and Image Data

Discuss your code, get questions answered

Canvas and Image Data

Postby ebkwall » Mon Apr 11, 2016 6:58 pm

Oliver,

If I knew JavaScript this would be a lot more fun. I am having a hard time finding *good* API reference material and examples for non web page javascript code.

I believe at some point I will have to ask how to load a js library thru the Asset Localization mentioned but I could not find instructions on actually doing it.

but on to the subject of this post. I want to load a Map Tile to the canvas. I believe code will do it but it just gives me a blank canvas. The url does create an map tile.

Code: Select all
    toDisplay: function(obj) {
        display.showGraphics(true);
        var context = canvas.getContext("2d");   
        var imageObj = context.createImageData(420, 640);
        var google_tile = "http://maps.google.com/maps/api/staticmap?sensor=false&center=-34.397,150.644&zoom=8&size=420x640";
        imageObj.src = google_tile;
        imageObj.onload = function(){
          context.drawImage(imageObj, 0, 0);
      };
    },
    eval: function(obj) { this.toDisplay(obj); },


Where am I going wrong?

Thanks much,
Brian
ebkwall
 
Posts: 22
Joined: Tue Apr 05, 2016 2:29 pm

Re: Canvas and Image Data

Postby oliver » Mon Apr 11, 2016 11:10 pm

MDN is the place to go for good documentation.

Yes, hobbling a JavaScript dev environment together can be not so fun. There're good ones, though. Webstorm is good, and so is JScript in VS.
On the web, jsfiddle.net or CodePen are really nice tools to semi-interactively try out ideas.

Lacking its own dev environment, for serious development for ND1, you'd want to develop your type outside ND1 in jsfiddle.net or something and then bring code that you know works back into the environment. If I find someone who wants to build it with me, I'd like to do a Web version using the calc engine (MorphEngine) and then you'd have an "IDE" through the Chrome debugger, which is very good.

About the code. I think you have only one small mistake that makes it not work.
Try this:
Code: Select all
    toDisplay: function(obj) {
        display.showGraphics(true);

        var imageObj = new Image();
        var google_tile = "http://maps.google.com/maps/api/staticmap?sensor=false&center=-34.397,150.644&zoom=8&size=420x640";
        imageObj.onload = function(){
          var context = canvas.getContext("2d");   
          context.drawImage(imageObj, 0, 0);
        };
        imageObj.src = google_tile;
    },


An image data object is not the same as an image. Setting the .onload() handler before .src is kinda crucial: if the data is already loaded (because it's cached), onload() will never be called, if you assign .src first.

You can also try
Code: Select all
     toDisplay: function(obj) {
         display.showImageFromURL("http://maps.google.com/maps/api/staticmap?sensor=false&center=-34.397,150.644&zoom=8&size=420x640");
    },

(This function is undocumented and probably of dubious value, but it happens to be there.)

By the way, display.showGraphics() switches the stack for a canvas, but you could do different things. You could display a live Google map, if you wanted. Or display static images inline along with your type on the stack (by providing a toHTML method that would return an <image> tag), etc. HTML5 is a pretty wide open world. (Albeit a not very structured one.)
oliver
Site Admin
 
Posts: 433
Joined: Sat May 01, 2010 2:11 pm

Re: Canvas and Image Data

Postby ebkwall » Tue Apr 12, 2016 8:24 am

Thanks. I see what I was doing wrong now.

Now if I can get this question answered - this is where I really want to go - I will be a happy camper.

ESRI has an extensive geospatial JavaScript API but I only know how to use it in web pages. I want to run this JavaScript on the ND1 canvas without having to load an html page from the web. Worst case I would like to generate html text and load it into the canvas. Better case I would like to work directly with the canvas and the ESRI JavaScript objects.

Side note, this API can do things such as geospatial analysis or attribute search and return raw data in json so if I can get the framework pieces in place this could be really fun.

Check out http://developers.arcgis.com/javascript/

Here is a basic fully interactive web map totally stripped down to only the essentials. In what ways can I bring this into ND1?
Can I work directly with the map object in some way?

You can save this to an html file and open It with a browser without going thru an iis server and have a fully interactive map. I think this dark map will look good on ND1.

Code: Select all
<html>
<head>
<link rel="stylesheet" href="http://js.arcgis.com/3.16/esri/css/esri.css"/>
<script src="http://js.arcgis.com/3.16/"></script>
<script>
var map;
require(["esri/map"],function(Map){map=new Map("map", {basemap:"dark-gray",center: [-70.6508, 43.1452],zoom:16});});
</script>
<style>html,body,#map{padding:0;margin:0;height:100%;width:100%;}</style>
</head>
<body><div id="map" class="map"></div></body>
</html>



Thanks much,
Brian
ebkwall
 
Posts: 22
Joined: Tue Apr 05, 2016 2:29 pm

Re: Canvas and Image Data

Postby oliver » Tue Apr 12, 2016 10:47 pm

Ok. This is getting more complicated.

Principally:
- yes, you can "require" (=get and use) external JavaScript in your functions
- you can even download it once and then access locally (see the BigInt downloadable folder and go to Sharing and notice the "Download Assets" button)
- you can add any kind of HTML because the display *is* HTML5

That is, you should be able to work with the ESRI Maps object. However, a) not exactly like you envisioned, and b) I failed to bring in the 50K lines of code that constitute the ESRI maps library with a couple of attempts.

About a): looking at your example HTML (which works for me), the ESRI library is initialized over a <div>, not a Canvas object. It doesn't use Canvas for drawing (which is a HTML5 drawing technology completely distinct from the world of DOM elements and CSS), but SVG (another drawing tech). So the standard canvas in ND1 doesn't do you any good. You wouldn't have to use it, though.

About b): in ND1 to dynamically load code you use a require() function. You can see its use in http://naivedesign.com/ND1/ND1_Reference__Custom_Types.html. I tried
Code: Select all
require("http://js.arcgis.com/3.16/");
which gives me an error (TypeError: undefined is not an object (evaluating 'p[1]._scopeName=p[0]')) and
Code: Select all
require("http://js.arcgis.com/3.16/", true);
which gives me a different error (Error: undefinedModule). These errors are thrown by the ESRI library. Not sure why but I speculate that maybe only the <script> method for loading in the <head> section is supported. ND1 uses two different methods (XHR request or <script> method in given <div>, depending on the boolean passed to require()).

You can also add extra HTML when you switch to graphics mode and include code with a <script> tag. I attempt that via
Code: Select all
display.showGraphics(true, '<script type="text/javascript" src="https://js.arcgis.com/3.16/"></script>');

That loaded the 1MB init.js file from ESRI but doesn't proceed to load other files that are loaded when you include this tag in the <head> section of a webpage.

So, sorry... without further heavy-duty debugging and trying to find a work-around I fear this isn't going to work.
Except, you can blow away the entire display and just load a webpage. (If you host your test page and type the URL in the edit line and push it, that should display the webpage fine.) You could programmatically do that by setting location.href, but I'm not sure that's what you're after.

Do you want to go full-screen and replace the entire display? Or do you want to show a (small) map in the running stack? The toHTML() function let's you return arbitrary HTML. If the require() above worked, you could return a '<div id="map" class="map"></div>' string, which would construct a div for you and then subsequently construct your Map object over that div. Lacking success loading this large library, maybe you can still show a map using static map API. The Map object's strength, I presume, is that it's interactive. That would be fine for fullscreen operation but might look and feel a little funny on a small map that's floating with the stack (and conflict with vertical scrolling).
oliver
Site Admin
 
Posts: 433
Joined: Sat May 01, 2010 2:11 pm


Return to Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron