Category Archives: HTML5

CSS Overlaying Controls (absolute and relative positioning)

Having looked at CSS in the past, and thought that it’s probably something that people who are better at UI design that me should concern themselves with, I’ve recently been playing with it while looking at the new Dot Net Core web apps.

The problem that I’m looking at in this particular article is how to overlay one control on top of another. I have no doubt that there are dozens of possibilities; but the two specific ones that I’ll be focusing on are positioning absolute and relative.

Target

The idea here is for a web-page that looks like this:

Target Layout

HTML

The HTML is pretty basic for this:

<body>
  <form>
    <div>
      <img src=""  />
    </div>
    <div class="overlay">
      <input type="text" name="destination" />
    </div>
  </form>
</body>

CSS: absolute positioning

We have the basic elements, so now it’s down to CSS to make the screen above. By default, web browsers will render the div’s sequentially, and so the input box will appear below the image.

One possibility is to use “absolute” positioning. This means that I can position an element without regard to where other elements on the page might be; here’s an example:

.overlay {
    position: absolute; 
    top: 30%;         
    text-align: center;
    z-index: 10;
}

img {
  background-color: blue;
  width: 100%;
  height: 500px;
}

I’ve used 30% here because it matters on the size of your viewport – so that’s not ideal. Also, the centre align doesn’t work. This kind of makes sense when you think about it, because you’re using an absolute position – so what do you want to centralise it to?

CSS: relative positioning

Relative positioning took me a while to work out. It sounds like it’s relative to something else – but it’s actually relative to itself. Here’s what I tried for relative positioning:

.overlay {
    position: relative;
    width: 80%;
    height: 35px;
    top: -50px;
    border: none;
    text-align: center;
    z-index: 10;    
}

As you can see, it’s top position is negative, so it moves up from where it would have been. Also, because the positioning is relative, the centre align now works, because it’s back in the flow of the page.

References

https://css-tricks.com/absolute-relative-fixed-positioining-how-do-they-differ/

https://www.w3.org/Style/Examples/007/center.en.html#block

Find user’s current location and display on Bing maps (v6.3)

Using Bing Maps to display the user’s current position should be an easy task. As with everything in Javascript, this kind of thing is only easy if you know the magic text.

HTML

<body onload="LoadMap();">
    <div class="row">
        <div>
            <h2>Where do you want to go?</h2>
        </div>
    </div>

    <div class="row">        
        <div id="pnlMap" style="position:relative">
        </div>
    </div>

There are a few points here: first one is that you need a name for the pnlMap (referenced later is the javascript), and style=”position:relative” prevents the map from just displaying in a random location.

Javascript

var map;

function LoadMap() {        
    map = new VEMap('pnlMap');    
    navigator.geolocation.getCurrentPosition(findMe);
}

function findMe(position) {
          
    var latlong = new VELatLong(position.coords.latitude,
        position.coords.longitude);
    map.LoadMap(latlong, 10);
}

LoadMap() sets up the map variable and associates it to the relevant HTML control, and then getCurrentPosition calls back to findMe(). The second number on LoadMap is the zoom level; 1 shows me as living on the earth, and 20 goes right into the road that I live on.

The output is a map that centres on your current location:

Slightly offset to avoid hordes of angry JS programmers beating down my door and suggesting that dynamically typed languages are as good as statically typed ones!

V6.3

As you will see from the references below, the latest version is v8. If you use v8, then you have to register for a key… but I didn’t want to… and I still got a map. I suppose I’ve done a bad thing.

References

https://www.w3schools.com/html/html5_geolocation.asp

https://msdn.microsoft.com/en-us/library/bb259692.aspx

https://msdn.microsoft.com/en-us/library/cc161074.aspx

https://social.technet.microsoft.com/wiki/contents/articles/34568.bing-maps-v6-3-to-v8-migration-guide.aspx

http://stackoverflow.com/questions/42607156/using-bing-maps-with-bootstrap

Back To Front (Scrolling a Vertical Game Background Using Windows 8, Javascript & HTML5)

I’m currently trying to write my first game using the Windows 8 platform. I’ve just finished a painful time trying to work out how to vertically scroll a repeating background. In my case, it’s a star-scape, but this should work for anything.

 

The Problem

 

Imagine you have a single image as a background to your game, but you want to make it look like your game is moving forwards (literally). However, also imagine that you’re incredibly bad at drawing, or manipulating images in any way – so you want to just use one image.

 

Caveat

 

This works for a star-scape because stars look pretty much the same unless you pay very close attention – obviously if you have a vertical shoot ’em up then this might not work, depending how innocuous you make the background.

 

The Solution

 

Okay, so my solution here was to simply scroll the background into itself. In order to do this, you have to visualise the background as a large sheet of paper, and the screen canvas as a small magnifying glass (but square). Strictly speaking, you don’t have to actually visualise it at all, because I’ve drawn it below:

 

background_1

Now, we can scroll that image downward, giving the impression that it’s moving (or we are):

background_2

That’s going to look like we’ve moved across the image. However, the eagle eyed amongst you may notice that we’ve now ran out of image! Actually, this is quite straightforward, just do what the BBC do when they run out of programs – repeat:

background_3

In Detail

Okay, so how do we do all that? It’s alarmingly difficult actually. I’ve marked this as a javascript post, but I don’t see why it wouldn’t work for any language – the principle and maths should be the same.

First, create a variable; for example:

var backgroundOffset = 0;

Inside your game loop, this needs to be iterated:

var gameLoop = function () {        
    canvasContext.clearRect(0, 0, canvas.width, canvas.height);

    // Draw Background
    ++backgroundOffset;
}

Then you need to actually draw the background. This does work, but I’m not claiming it’s the most efficient way of doing it:


canvasContext.drawImage(backgroundImage, 0, backgroundOffset);

if (backgroundOffset >= 0 &amp;&amp; backgroundOffset <= canvasHeight) {
    canvasContext.drawImage(backgroundImage, 0, backgroundOffset - backgroundImage.height);
}

// Scrolling off the bottom of the screen
if (backgroundOffset > canvasHeight) {
    backgroundOffset = canvasHeight - backgroundImage.height;
}

Conclusion

If, like me, you’re just dabbling in game development and want something that gives the impression of moving, then this will do it. If you want Call Of Duty then you’re going to need something more complex!

Gesture of Goodwill in HTML5

This is the second time I’ve typed this. For some reason, WordPress musn’t have liked the first attempt, and so trashed it – which is annoying!

I’ve been playing with gestures on HTML5, and encountered a strange problem (this may be peculiar to Windows 8, but I doubt it).  Here’s the scenario:

The Problem

You have an app (remember that we’re talking about Windows 8).  In the app, you have a particular response to a swipe gesture: say you want to record the swipe distance; and to react to a tap / touch gesture.  This works for mouse events, too.

Here’s some code:

<body>
    <canvas id="mainCanvas">

    </canvas>
</body>

Yeah – I know, you’re wondering how I ever managed to get so good at HTML5!

Here’s some more interesting code:


    var canvas;
    var canvasContext;

    var initialiseApp = function () {
        canvas = document.getElementById("mainCanvas");
        canvasContext = canvas.getContext("2d");

        canvas.width = window.outerWidth;
        canvas.height = window.outerHeight;

        // define GestureRecognizer  
        var recognizer = new Windows.UI.Input.GestureRecognizer();
        recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
        recognizer.addEventListener('manipulationcompleted', function (e) {
            var dx = e.cumulative.translation.x

            canvasContext.clearRect(0, 0, 1000, 20);
            canvasContext.fillStyle = "#2F1BE0";
            canvasContext.fillText('manipulationcompleted ' + Date.now(), 10, 10);
            
        });

        // actual element which feeds the GestureRecognizer  
        var processUp = function (evt) {
            try {
                recognizer.processUpEvent(evt.currentPoint);

                canvasContext.clearRect(10, 90, 1000, 50);
                canvasContext.fillStyle = "#2F1BE0";
                canvasContext.fillText('processUp' + Date.now(), 10, 100);

            }
            catch (e) { } 
        }

        canvas.addEventListener('MSPointerDown', function (args) {
            try {
                recognizer.processDownEvent(args.currentPoint);

                canvasContext.clearRect(10, 190, 1000, 20);
                canvasContext.fillStyle = "#2F1BE0";
                canvasContext.fillText('processDown' + Date.now(), 10, 200);
            }
            catch (e) { } 
        }, false);

        canvas.addEventListener('MSPointerMove', function (args) {
            try {
                recognizer.processMoveEvents(args.intermediatePoints);

                canvasContext.clearRect(10, 250, 1000, 200);
                canvasContext.fillStyle = "#2F1BE0";
                canvasContext.fillText('processMove' + Date.now(), 10, 300);
            }
            catch (e) { } 
        }, false);
        canvas.addEventListener('MSPointerUp', processUp, false);
        canvas.addEventListener('MSPointerCancel', processUp, false);

    }

If you try that, you’ll notice something… or at least you will now I’ve told you to. That is that if you click / touch then you get a mouse up, but if you swipe then you get a mouse up and a manipulationcomplete! Good God – BOTH! But what if you only want to react to one? Say you have a fishing game, and the swipe casts the … err fishing string thingy, and the touch reels the … err… okay, maybe I should have picked an example I know something about, but you get the idea.

The Solution

I don’t like it, but here’s my answer to that particular conundrum:

    var canvas;
    var canvasContext;
    var eventFlag = 0;

    var initialiseApp = function () {
        canvas = document.getElementById("mainCanvas");
        canvasContext = canvas.getContext("2d");

        canvas.width = window.outerWidth;
        canvas.height = window.outerHeight;

        // define GestureRecognizer  
        var recognizer = new Windows.UI.Input.GestureRecognizer();
        recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
        recognizer.addEventListener('manipulationcompleted', function (e) {
            var dx = e.cumulative.translation.x

            canvasContext.clearRect(0, 0, 1000, 20);
            canvasContext.fillStyle = "#2F1BE0";
            canvasContext.fillText('manipulationcompleted ' + Date.now(), 10, 10);
            eventFlag = 1;
            
        });

        // actual element which feeds the GestureRecognizer  
        var processUp = function (evt) {
            try {
                recognizer.processUpEvent(evt.currentPoint);

                if (eventFlag == 0) {
                    canvasContext.clearRect(10, 90, 1000, 50);
                    canvasContext.fillStyle = "#2F1BE0";
                    canvasContext.fillText('processUp' + Date.now(), 10, 100);

                } else {
                    eventFlag = 0;
                }

            }
            catch (e) { } // translateYfails ?!  
        }

So we have a flag, and only do something based on the flag.

Conclusion

If there’s a better way of doing this then I’d like to hear. It would be particularly nice if you could get the return value of processUpEvent, or set some kind of handled flag. Having said that, this does work.