Category Archives: HTML5

Building a list with Asp.Net Core

I’ve recently been working with Asp.Net Core to build some functionality, involving building a list of values. Typically, with Asp.Net Core using Razor, you have a form that may look something like this:

@using (Html.BeginForm("MyAction", "ControllerName", FormMethod.Post)
{
    @Html.AntiForgeryToken()
    <div class="form-group">
        @Html.LabelFor(model => model.MyValue)
        @Html.TextBoxFor(model => model.MyValue)
    </div>

    <div class="form-group">
        <button type="submit">Submit</button>
    </div>

This works really well in 90% of cases, where you want the user to enter a value and submit. This is your average CRUD application; however, what happens if, for some reason, you need to manipulate one of these values? Let’s say, for example, that you want to submit a list of values.

For the sake of simplicity, we’ll say that the controller accepts a csv, but we want to build this up before submission. You can’t simply call a controller method for two reasons: the first is that the controller will reload the page; and the second that you don’t have anywhere to put the value on the server. If this was, say, a method to create an entry in the DB, the DB entry, by definition, couldn’t exist until after the submission.

This all means that you would need to build this list on the client.

A solution

Let’s start with a very simple little feature of Html Helpers – the hidden field:

@Html.HiddenFor(model => model.MyList)

This means that we can store the value being submitted to the user, without showing it to the user.

We’ll now need to display the data being added. An easy way to do this is a very simple table (you can load existing values into the table for edit scenarios):

    <div>
        <table id="listTable">
            <tbody>
                @if ((Model?.ValueList ?? null) != null)
                {
                    @foreach (var v in Model.ValueList)
                    {
                        <tr>
                            <td>@v</td>
                        </tr>
                    }
                }
            </tbody>
        </table>
    </div>    

Pay particular attention to the Table Id and the fact that the conditional check is inside the tbody tag. Now let’s allow the user to add a new piece of data:

    <div class="form-group">
        @Html.LabelFor(model => model.NewValue)
        @Html.TextBoxFor(model => model.NewValue)
    </div>
    <div>
        <button type="button" id="add-value">Add Value</button>
    </div>

Okay, so now we have a button and a field to add the value; we also have a method of displaying those values. We’ll need a little bit of Javascript (JQuery in this case) to append to our list:

@section Scripts {
        $('#add-value').click(() => {

            const hiddenList = $('#MyList');
            const newValue = $('#NewValue');

            if (!hiddenList.val()) {
                hiddenList.val(newValue.val());
            } else {
                hiddenList.val(hiddenList.val() + ',' + newValue.val());
            }
            
            $('#listTable > tbody:last-child').append('<tr><td>' + newValue.val() + '</td></tr>');            
        });

On the button click, we get the hidden list and the new value, we then simply add the new value to the list. Finally, we manipulate the table in order to display the new value. If you F12 the page, you’ll notice that the Razor engine replaces the Html Helpers with controls that have Ids the same as the fields that they are displaying (note that if the field name contains a “.”, for example: MyClass.MyField, the Id would be MyClass_MyField).

When you now submit this, you’ll see that the hidden field contains the correct list of values.

References

https://stackoverflow.com/questions/16174465/how-do-i-update-a-model-value-in-javascript-in-a-razor-view/16174926

https://stackoverflow.com/questions/171027/add-table-row-in-jquery

https://stackoverflow.com/questions/36317362/how-to-add-an-item-to-a-list-in-a-viewmodel-using-razor-and-net-core

Using Blazor Components

Imagine that you’re writing a Blazor application – maybe it’s similar to this one. Now, imagine that you have a large chunk of HTML in your main view. You might think: I wish I was using React, then I could separate this into its own component.

You can also do this in Blazor. Here’s how.

Components in Blazor

Let’s start with moving your code. The first step is to cut your HTML and paste it into a new Razor Component:

The format of your new component, from scratch, will be:

&lt;h3&gt;Component Name&lt;/h3&gt;

@code {

}

Your existing code should go beneath, or instead of:

&lt;h3&gt;Component Name&lt;h3&gt;

Parameters

The @code section allows you to put all kinds of crazy C# code in a code behind type model – so you probably don’t want to use that, except for passing parameters; for example:

@code {
    [Parameter]
    private string MyParameter { get; set; }
}

This allows you to pass a string into your component; for example (in your main view):

&lt;MyComponent MyParameter=&quot;test&quot; /&gt;

Complex Parameters

So far so good. But what if you need a complex type? You could, for example, pass a View Model into your component:

[Parameter]
private MyViewModel MyViewModel { get; set; }

You can pass this into the component as though it were a primitive type:

&lt;MyComponent MyViewModel=&quot;@MyViewModel&quot; /&gt;

This means that you can lift and shift the code with no changes.

Using External Namespaces

As with standard C#, you can access anything within the current namespace. Should you need any classes that are not in your current namespace, you can declare them at the top of the file, like this:

@using MVVMShirt

&lt;h3&gt;My Component&lt;/h3&gt;

Summary

Blazor is still in its infancy, but hopefully, adding actual code to these @code sections will become as frowned upon as code-behind.

Using View Models in Blazor

Being new to Blazor (and Razor), the first thing that tripped me up was that the view seemed divorced from the rest of the application. In fact, this is actually quite a nice design, as it forces the use of DI.

For example, say you wanted to create a View Model for your view, you could register that ViewModel in the Startup:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<MyViewModel, MyViewModel>();
        }

Note here that you don’t need an interface. If you’re only creating an interface for the purpose of this then that abstraction provides no benefit. That isn’t to say there may not be a reason for having an interface, but if you have one and this is the only place it’s used, you probably should reconsider.

The views in Razor / Blazor (at the time of writing) are *.razor files. In order to resolve the dependency inside the view, you would use the following syntax:

@page "/"
@inject ViewModels.MyViewModel MyViewModel

(Note that @page “/” is only in this snippet to orientate the code.)

You can call initialisation in the view model using something like:

@code {

    protected override async Task OnInitAsync()
    {
        await MyViewModel.Init();
    }    
}

And, within your HTML, you can reference the view model like this:

<div>@MyViewModel.MyData</div>

Magic. Hopefully more to come on Blazor soon.

Adding a New Screen to the React Template Project

In this post I started looking into ReactJS. Following getting the sample project running, I decided that I’ve try adding a new screen. Since it didn’t go as smoothly as I expected, I’ve documented my adventures.

The target of this post is to create a new screen, using the sample project inside Visual Studio.

Step 1

Create a brand new project for React:

If you run this out of the box (if you can’t because of missing packages then see this article), you’ll get a screen that looks like this:

Step 2

Add a new tsx file to the components:

Here’s some code to add into this new file:

import * as React from 'react';
import { RouteComponentProps } from 'react-router';
 
 
export class NewScreen extends React.Component<RouteComponentProps<{}>, {}> {
    public render() {
        return <div>
            <h1>New Screen Test</h1>
        </div>;
    }
}
 

The Javascript as HTML above is one of the things that makes ReactJS an appealing framework. Combine that with Typescript, and you get a very XAML feel to the whole web application.

Step 3

Add a link to the Navigation Screen (NavMenu.tsx):

<div className='navbar-collapse collapse'>
    <ul className='nav navbar-nav'>
        <li>
            <NavLink to={ '/' } exact activeClassName='active'>
                <span className='glyphicon glyphicon-home'></span> Home
            </NavLink>
        </li>
        <li>
            <NavLink to={ '/counter' } activeClassName='active'>
                <span className='glyphicon glyphicon-education'></span> Counter
            </NavLink>
        </li>
        <li>
            <NavLink to={ '/fetchdata' } activeClassName='active'>
                <span className='glyphicon glyphicon-th-list'></span> Fetch data
            </NavLink>
        </li>
        <li>
            <NavLink to={'/newscreen'} activeClassName='active'>
                <span className='glyphicon glyphicon-th-list'></span> New screen
            </NavLink>
        </li>
 
    </ul>
</div>

If you run this now, you’ll see the navigation entry, but clicking on it will give you a blank screen. It is just that scenario that motivated this post!

Step 4

Finally, the routes.tsx file needs updating so that it knows which screen to load when:

import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import { NewScreen } from './components/NewScreen';
 
export const routes = <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={FetchData} />
    <Route path='/newscreen' component={NewScreen} />
</Layout>;

Playing multiple videos simultaneously using HTML5

I was interested to see how playing multiple videos simultaneously affected the performance of a web page. This probably seems a little like a time machine back to 1995 – I’ll soon be posting about flashing red text and Dreamweaver!

However, playing short videos with only a few frames can be a way to draw attention to a particular part of the page; for example, if you’re browsing a clothing catalogue and one of the models moves when you hover over.

It’s worth pointing out that the entire page will be local, and so I have no network considerations whatsoever. This isn’t, however, about having three Netflix streams running at the same time – it’s short, and small videos.

The video that I’m using came from here. I’m creating an effect whereby you hover over an image of a space ship and it explodes.

MP4

It’s worth bearing in mind that most video formats are not supported by most browsers. MP4 is the exception, so it looks like this is the way to go for video encoding. I used this tool to convert the file.

HTML

Here’s the HTML for a single icon:

<head>
  <script src="HoverAnimate.js"></script>
</head>
<body onload="loaded()">
  <div id="ship1" style="background-image: url('assets/titan.png'); background-repeat: no-repeat; background-size: 50px 50px; width: 50px; height: 50px">
    <video  width="50" height="50" id="ship1-video" 
            style="visibility: hidden">
      <source src="assets/explosion.mp4" type="video/mp4" />
    </video>
  </div>
</body>

Clearly this could be neater if the CSS was separated, but essentially what we have is a div element with a scaled background image, which contains a video (currently hidden). The next thing is the Javascript that plays the video:

function loaded() {
    var imgs = document.getElementsByTagName("div");
    [].forEach.call(imgs, function (item) {
        if (item.style.backgroundImage !== "") {
            item.addEventListener('mouseover', hoverImg, false);
        }
    });
   
}

function hoverImg(e) {      
    var vid = document.getElementById(this.id + "-video");
    vid.onended = function() {        
        vid.style.visibility = 'hidden';
    }
        
    vid.style.visibility = 'visible';
    vid.play();
}

This iterates through all the div elements and, for those that has a background image, hooks up a hover event. I’ve also assumed that the div element will be named using the format “{imagename}-video”.

Conclusion

I tried this with seven videos simultaneously, and didn’t see any jerking of the animations. Whether this would stand up under networked conditions, it’s hard to say, but with the video locally available, performance is fine.

References

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

http://www.online-convert.com/

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

http://www.dreamincode.net/forums/topic/281583-video-plays-on-mouse-over-but-not-with-multiple-videos/

https://stackoverflow.com/questions/10881678/html-play-a-video-inside-an-image

Create CSS effect to “Shine” a button border

Imagine that you have an HTML button or element on a page and you would like an effect where the border shines all around the perimeter. this provides an excellent example of an effect of the entire element shining, and this post will largely be based on that code.

Animations

CSS has the concept of an animation, to define it, use the following syntax:

.growOnHover:hover:after {
    animation: growAnimation 1s;
}

Here is the HTML referencing this:

<a href="#" class="growOnHover">Grow</a>

Tge “growAnimation” refers to a KeyFrame:

@keyframes growAnimation {
    from {width: 100px; height: 100px;}
    to {width: 110px; height: 110px;}
}

The effect

The effect that I want is for a light to run around the circumference of the button when it’s hovered over. In this case, instead of animating from .. to, we can specify at which stage a particular section of the animation kicks in.

.borderShine:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 5;
  height: 5;
  opacity: 0;  

  border-radius: 1;

  background: rgba(255, 255, 255, 10);
}

.borderShine:hover:after {
  animation: shineAnimation 2s 1;  
}

@keyframes shineAnimation {
  0%   {left: 0; top: 0; width: 2; height: 2; opacity: 0}
  10%  {width: 100; height: 2}  
  20%  {left: 98; top: 0; width: 2; height: 2}
  25%  {opacity: 1;}
  30%  {height: 100}
  40%  {left: 98; top: 98; height: 2}
  50%  {left: 0; top: 98; width: 100}
  55%  {opacity: 1;}
  60%  {left: 0; top: 98; width: 2; height: 2}
  70%  {left: 0; top: 0; width: 2; height: 100}
  80%  {left: 0; top: 0; width: 2; height: 2}
  100% {opacity: 0;}
}

There are a few useful things to remember here:

  • The animation is a transition between the state that the screen is currently in, and the state that you want it to be in; so, for example, the opacity set to 1 at 25% will cause the white bar to gradually appear over the steps between the two. The reason that I’ve set opacity twice here is to prevent it from transitioning back too soon.
  • All the figures above are absolute (as my buttons are 100 x 100).

References

http://jsfiddle.net/AntonTrollback/nqQc7/

https://css-tricks.com/useful-nth-child-recipies/

https://css-tricks.com/using-multi-step-animations-transitions/

Rotate a Shape Around an Axis Using HTML5 and Javascript

Imagine, for a minute, that you want to rotate a red square around its centre… on a web page. Following on from my previous post about games using HTML5 / JS this post details how to do such a thing.

Context

Before drawing a rectangle, rotating it, or anything else, you need a context:

var canvas = document.getElementById("mainCanvas");
var ctx = canvas.getContext("2d");

Now you have a context, you can do things like clear the canvas; for example:

ctx.clearRect(0, 0, windowWidth, windowHeight);

fillRect

In HTML5, you have three methods that will be of use, and the first, and probably most important, is fillRect. It is impossible to rotate a square around its centre without a square. The syntax for fillRect is probably as you would expect:

ctx.fillRect(x, y, width, height);

rotate

The syntax for rotation is this:

ctx.rotate(rotationDegree * Math.PI / 180);

Whilst I may, during my school years, have been able to explain the sum above – I just copied it from the internet. Given the number of places where is looks exactly alike, I would guess that I’m not the first person to do that.

Just using the three lines above will give you a rotating rectangle; however, the rotation axis will be 0, 0. It took me a while to understand exactly how this works, but the key is `translate`.

translate

To me, this function is completely counter-intuitive. What it does it to offset the centre of the context by the parameters given. If the initial centre is 0, 0 (which it is by default), the following line will make it 10, 10:

ctx.translate(10, 10);

The centre of the context is 10, 10; if I call it a second time:

ctx.translate(10, 10);

The centre of the context is now 20, 20! There are two ways to reset the offset – you can simply negate the offset (by calling it with negative values), or you can call ctx.save() before the change, and ctx.restore() afterwards.

Putting it all together

So, what does all this look like in a single coherent piece of code:

        var canvas = document.getElementById("mainCanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, windowWidth, windowHeight);

        var halfWidth = (iconWidth / 2);
        var halfHeight = (iconHeight / 2);

        var centreX = x - halfWidth;
        var centreY = y - halfHeight;

        ctx.fillStyle = "#FF0000";
        ctx.translate(centreX, centreY);
        ctx.rotate(rotationDegree * Math.PI / 180);
        ctx.fillRect(-halfWidth, -halfHeight, iconWidth, iconHeight);

        ctx.translate(-centreX, -centreY);

The key part to note here is the call to fillRect. Because the translate has now set the centre to be the centre of the drawn image, the image needs to be positioned at -(image width / 2).

… and you, too can have a spinning red rectangle on your screen.

References

http://www.w3resource.com/html5-canvas/html5-canvas-translation-rotation-scaling.php

https://gist.github.com/geoffb/6392450

Basic Game Using HTML5 and Javascript

This article discusses how to go about creating a basic game loop in HTML5 / JS and to implement control over a sprite.

Introduction

A few years ago, when Microsoft released the idea of WinJS, I wrote a game in HTML5/JS (or WinJS – they are not exactly the same).

I recently decided to see if I could write a web game, using just HTML5 and Javascript. This article covers the initial POC and results in a small red square navigating around the screen:

Game Loop

Looking at established game frameworks, they all basically give you the same things:
– A game loop, consisting of an update and draw phase
– Some helper methods for manipulating graphics, or rendering them to the screen

My attempt will be different, I’ll just provide a game loop; here it is:

(function MainGame() {    

    setInterval(function() {
        Update();
        Draw();
    }, 20);
})();

The loop executes every 20ms, meaning that there are 50 frames per second.

HTML

Basically, what the HTML gives us here is a canvas; so the page is very simple:

<head>    
    <script type="text/javascript" src="./gamelogic.js" ></script>
</head>
<body onresize="onResizeGameWindow()">    
    <canvas id="mainCanvas" style="width: 100%; height: 100%"
        onkeydown="onKeyDown()" tabindex="0">
    </canvas>
</body>

There are two events handled here, because there are two things that the player can do: they can interact with the game (i.e. press a key), and they can resize the browser window. We need to react to both.

Draw

Let’s have a look at the draw function next. All this is, is a way of displaying all the objects on the screen in a controlled fashion:

    function Draw() {
        var canvas = document.getElementById("mainCanvas");
        var ctx = canvas.getContext("2d");
        ctx.clearRect(0, 0, windowWidth, windowHeight);

        ctx.fillStyle = "#FF0000";
        ctx.fillRect(x, y, iconWidth, iconHeight);
    }

As you can see, there are effectively two parts to this function: firstly, the canvas is cleared, and then the items (in this case, a single item) are drawn to the screen. The important variables here are x and y, because that dictates where the square is drawn; the rest could be hard-coded values.

Update

    function Update() {        
        if (initialised == 0) {
            initialise();
        }

        // Bounce
        if (x >= (windowWidth - iconWidth) 
            && directionX > 0)
            directionX = -1;
        else if (x <= 0 && directionX < 0)
            directionX = 1;

        if (y >= (windowHeight - iconHeight)
            && directionY > 0)
            directionY = -1;
        else if (y <= 0 && directionY < 0)
            directionY = 1;

        // Move
        x += directionX * speed;
        y += directionY * speed;
    }

There are three parts to the Update. The first is to perform any initialisation: in my case, I focus on the canvas and call the resize event here. This potentially could be done on an event, but you would still have to check inside this loop if it had been done. The second is to stop the player leaving the screen; and finally, we adjust the player position.

Events

As you saw earlier, there are two events that are handled; the first is the user resizing the screen:

function onResizeGameWindow() {
    var canvas = document.getElementById("mainCanvas");
    
    windowWidth = canvas.width;
    windowHeight = canvas.height;
}

This basically ensures that the game adjusts to the browser dimensions. This might also be where you would determine if the window was made so small that the game could no longer be played.

The second event was the keydown event. This effectively provides the control for the player:

function onKeyDown(e) {
    if (!e) e = window.event;     

    if (e.keyCode == 39) {
        directionX++;
    }
    else if (e.keyCode == 37) {
        directionX--;
    }

    if (e.keyCode == 38) {        
        directionY--;
    }
    else if (e.keyCode == 40) {        
        directionY++;
    }
}

The top line is because the parameter comes through as null.

Conclusion

If you run this game, you’ll see that you can move the square around the screen, increase and decrease its speed, and stop. Not exactly the next Call Of Duty, I’ll grant you, but the foundation of a game, certainly.

Create a Web Page to Find an Address Using Bing Maps 6.3

This post discusses how you might implement an address search with Bing Maps.

Disclaimer

I know that Bing Maps 6.3 is shortly to be deprecated. When I get around to signing up for v8 I might post an update to this.

Display the map

Below is a basic HTML page that has a map control. For details on how that works, please see here.

    <form class="row">
        </div>                

        <div class="overlay">
            <input type="text" id="destination" placeholder="Where do you want to go?" 
                   class="input-overlay" oninput="ChangeDestination(this.value);" />
        </div>        
    </form>

    <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>
    <script type="text/javascript" src="~/Scripts/MyScript.js"></script>

There’s not too much to note in this HTML, with the possible exception of the oninput function. I spent a while trying to get onchange and onkeypress to work, but oninput is a HMTL5 specific feature, and it fires when there is a change in the input box; onchange does not. onkeypress does, but you’re always a key-stroke behind.

Here’s the Javascript function in MyScript.js (referenced above):

function ChangeDestination(text) {
    map.Find("", text);
}

This causes Bing Maps to go looking for the address that you pass it. It still needs work, as you will see if you start typing any place name – it’ll match whatever you’ve typed as best it can… and you’ll travel the world before you get where you’re going.

Further Thought

One possible work around for this might be to poll the text from javascript every second and determine whether it changed; however, there is another approach:

First, change the HTML to point to a caller function:

            <input type="text" id="destination" placeholder="Where do you want to go?" 
                   class="input-overlay" oninput="callChangeDestination(this.value);" />

And then, set a timeout, so that the function is only called if we don’t re-call it within a second:

var timeout;
function callChangeDestination(text) {
    
    clearTimeout(timeout);
    timeout = setTimeout(function () { ChangeDestination(text); }, 1000);       
}

Change the ChangeDestination function itself to clear the timeout:

function ChangeDestination(text) {
    clearTimeout(timeout);
    …

Now, as you type, it will only update the map when you pause.

References

http://stackoverflow.com/questions/20420429/what-the-difference-between-window-settimeout-and-settimeout

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