codefoster | All posts tagged 'metro'
Jeremy Foster
@codefoster

App Art

by Jeremy Foster 15. April 2013 13:53

One of my favorite steps in the app development lifecycle is the creation of the artwork. I'm not stellar at creating original artwork, but I definitely recognize when things look just right, and sometimes I stumble upon it. I must also have a little bit of marketing in me, because it's my constant effort to brand things.

The artwork and branding is important, because an app developer must live in a constant state of capturing the user amid so much noise. An app needs to say "here's precisely what I do and how it adds value to your life". It takes a lot of design thought and effort to cut through the noise and reach your audience.

Good messages to communicate are: clean, simple, creative, elegant, and fluid.

I'd like to walk you through my process of creating artwork for an app called Everyview. Everyview is webcam viewer that attempts to implement well the design principles of Windows 8. It's intended to feel like a breath of fresh air. There are plenty of apps for viewing web cams and it's nothing that can't be done in the browser too, but it's seldom a consolidated and elegant experience. As of this writing, Everyview is not yet published to the Windows Store, but by the time you read it, it may be. Try searching for Everyview.

My artwork for Everyview started with the creation of a symbol. The symbol had to represent every image that could possibly come through the eye of a camera and so I simply chose to represent the eye of a camera. I didn't want to make the app subject to aging by choosing a specific camera though, and I didn't want to specify a still camera or a video camera. So I created a camera lens. The icon doesn't determine absolutely that you're looking down the barrel of a DSLR, an amateur video camera, a high-end video camera, or any other specific model. It's an agnostic character of a camera.

Looking into the eye of a camera invokes a bit of a "live" feeling, as if you're on the air. I chose not to embellish the icon with a lot of gradients and or other attempts to make it look more realistic. As long as it says "camera" to the user, that's enough. I did, however, ad a lens glare that identifies it without doubt as a camera lens.

Let me show you how I created this image.

I used CorelDRAW because… well, because I always use CorelDRAW. Use your graphics package of choice, but don't restrict yourself to a bitmap editor. Creating images in a vector-based graphics package has serious benefits and will make exporting to the various required app graphic sizes a breeze. Creating images in a bitmap package will inevitable find you needing a size larger than what you designed for. I recorded a primer on using CorelDRAW and you can access it at http://aka.ms/coreldrawprimer.

Before I show you how I created that image, let me show you how I set up CorelDRAW for creating images for Windows 8. Choosing File | New in CorelDRAW by default will start you out with a document the size of a piece of paper. CorelDRAW is very good at creating artwork for print, but we're concerned here more with pixels than we are with inches, so let's change the defaults and save it for future use.

I created a preset called Win8 App that uses the base Windows resolution of 1366 x 768 pixels. I also chose a color mode of RGB since the results are to be rendered to a screen rather than a printer. When you're working with documents of a designated pixel width/height, the resolution I mostly irrelevant.

If you'd like a nice place to start, try downloading the template I created at http://codefoster.com/w8tiletemplate.

Now, with a new document, we can go about creating our camera lens graphic.

Creating the lens graphic

Create a series of concentric circles like so. You do this by creating the largest and then resizing it with the CTRL key held to resize about the object's center and hitting the right mouse button when you have your next circle to create a copy.

Use the second largest to trim the largest by clicking first the second largest and then holding shift and clicking the largest. Then hit the trim button on the toolbar. Then delete the second largest circle. Setting the fill color of all objects to black and removing the outline color should leave you with something like this…

That's nice and simple and we have only to create the lens glare, which is only slightly harder than what we've done so far.

Make another couple of circles inside the smallest. I like to give them a red outline (right click on red from the color palette) while I'm working so they're easily discerned.

When you draw an ellipse (in this case a circular ellipse) in CorelDRAW, you have an ellipse, which is different from a custom curve. Ellipses have the property that you can grab their little vertex using the shape tool and drag to reduce the ellipse to an arc. Use the shape tool (F10) to do just that and work your way to something like this…

And then use some trimming and intersecting to end up with this…

Designing the tiles

Now it's time to design yourself some tiles. At a minimum, you'll need a standard app tile (150 x 150), a small logo (30 x 30), a store logo (50 x 50), and a splash screen (620 x 300). Additionally, you can design a wide logo (310 x 150) and some additional promotional images in case the Store finds your app worthy of being featured. It's recommended that the wide logo only be used if you're going to implement a live tile.

Let's start with the main app tile. Here's what I came up with for that…

Obviously, the tile incorporates the symbol we just created, but I also add a stylized app title below that. I chose a fairly bold font, condensed it, used different colors for the words and even shoved them together and created a little notch. Little design choices like this are somewhat arbitrary, but will end up becoming your brand and how people recognize your app. Finally, I added a soft gradient behind the entire title. You have to be careful with gradients in modern apps, but a shallow, gray gradient here seems to add a sort of dreamy, modern, cloud feel to the app.

Next, I'll elaborate a bit on the standard logo design when creating the wide logo and the splash screen which I tend to make rather similar. Here's what I came up with.

Now with more horizontal space than vertical, we stretch the brand elements out left to right and I like to add a little subtitle that describes without a doubt what the purpose of the app is – it's a webcam viewer. Like the notched v in view, I notch the E with the camera lens and keep all of the graphics tight and bold.

The last step is the creation of the store and small logos.

The Store logo

The store logo is used for your apps dedicated detail page in the Windows Store. It's common practice to just shrink the app tile down from 150 pixels to 50 and call it good, but that's unfortunate because it's rare that the app's main tile will look so good at this size. Take a look at the Bing app's Store logo captured from its page in the Store…

You want this image to be even simpler than the main app tile, to use most of the 50 x 50 pixel space, and to have a transparent background.

For my Everyview app, I stuck to the basic, original symbol. In CorelDRAW if you want to render something out a certain size even if the elements inside don't quite fill up that size, you just create a bounding rectangle the size you want and then give it no fill and no outline. I have rendered this bounding box orange below for visibility only. To export this image, you simple set the bounding box's outline color to none (invisible), select the entire group (bounding box and symbol together), and then export (CTRL + E) it.

Here's how that would be rendered, however.

Notice a few things about this:

  • The image has been rendered to pixels custom made for the export size chosen (it could be rendered absolutely huge and would still look great)
  • The bounding box is not visible, yet it is responsible for the overall size and shape of the exported image
  • The background is transparent (designated by the checkerboard pattern) but the lens glare is always white
  • The transparency is 24-bit which means it has various levels of transparency around the edges to make it blend perfectly with the background
  • There is a little bit of space around each edge of the symbol
  • The symbol is large enough to capture all the quality we can in this restricted space

The small logo

The small logo is used to represent your app when the user semantically zooms out of their start screen. Try it and see.

You can use the exact same techniques to create the small logo as you did for the Store logo. The small logo (30 x 30 pixels) is even smaller than the store logo (50 x 50 pixels) so it becomes that much more important to be intentional about simplifying your image.

That's as far as I'll take this for now. Of course, you would continue your design effort into the app itself so that the entire effort is unified and consistent.

I'd like to point out one of the advantages to Microsoft design principles that ends up being highlighted by the content of this article. No part of the splash screen or the tiles or even the app itself are contributed to by Windows. The entire space falls under the responsibility of whoever wears the design hat in your organization (even if you are your organization and you wear all the hats!). The app tiles as well as the app's main design surface because a truly empty canvas and 100% of the pixels are there to deliver your brand, deliver your functionality, and delight your user.

Have fun with this. It's fun stuff for sure.

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

Design | Windows 8

Jump Start Your Brain

by Jeremy Foster 20. September 2012 17:40

My colleague Michael Palermo and I are scheduled to present two Jump Start video series on Channel 9. The first will cover basic HTML, CSS, and JavaScript development, and the second will cover those web technologies as they apply to creating Windows 8 apps.

You can get a lot more information about this content and register to attend by going to http://aka.ms/Win8Dev-JS.

Tags: , , , , , , , , , , , ,

CSS | HTML | JavaScript | Windows 8

Windows 8 App Bar Icons (from Segoe UI)

by Jeremy Foster 18. August 2012 23:04

UPDATE: since writing this I've found this MSDN article that I think has more information than my post. Hope that's helpful.

This is a reference post. Come back when you, like me, forget which icons are available to use on your application bar in your Windows 8 app. A larger version is attached here: AppBarIcons.jpg (223.22 kb).

If you define your app bar imperatively (in JavaScript), then you would simply pass the name of the icon from this graphic in as the icon option like so…

new WinJS.UI.AppBarCommand({..., icon:'bookmarks', ...})

Here’s the chart for those with young eyes :)

AppBarIcons

Tags: , , , , , , , , , , , , , , , , , , , , , , ,

Windows 8

Windows 8 App Design Sheet

by Jeremy Foster 28. June 2012 12:48

Attached is a worksheet that might help you when you’re brainstorming the design of your Windows 8 app.

It encourages the 3-tier navigation structure that’s common with these apps. The grid units are 1 unit (20 pixels). There are rules for the top and left margins (5 units and 6 units respectively) as well as for an app bar (88 pixels) and for snapped view (16 units).

If I modify it, I will replace the attachment here so that you can always come back to this post to download more sheets. It helps to have a few of these printed out and stashed in your computer bag.

Hope it helps.

Windows 8 App Design Sheet.pdf (152.25 kb)

Tags: , , , , , , , ,

Design | Windows 8

One Sweet Stack

by Jeremy Foster 21. June 2012 14:36

Following is a mongo post. A huge post. A massive amount of information. The general recommendation is that blog posts should be short, but rules are made to be broken. You can’t tame me. I’m like a wild stallion. So here is a huge blog post.

Last Saturday at the Seattle Code Camp I delivered a presentation I called One Sweet Stack which showed how to start with a SQL Azure database (though it would work with any relational database really), connect to it using Entity Framework, and extend it as OData with WCF Data Services.

I chose this stack because…

  • I come from corporations that have existing database solutions. These aren’t modern, green-field databases of the myriad of flavors. These are classic, tried-and-true, and very much relational. I’m as excited as the next guy all of the modern ways to persist data, but don’t think for a minute that the relational database story is obsolete. Far from it.
  • I love using Entity Framework. I get a little jolt of excitement when I instantiate a DbContext or call SaveChanges(). Geeky? Of course.
  • I think that WCF DS is oft overlooked and recently especially in light of WebAPI (which is also a great product). I’m a fan of designing a database, mapping it through an ORM, and providing an elegant API (whether it’s internal or external) with so little code that I can write it from scratch in a 1 hr session (including explanations).
  • Windows 8 thrills me even more than EF.

I’m hoping to convey virtually all of the content from the presentation here, so it will be a heavy post. Consider it a reference post and come back to it if/when you need it.

The source code for this project is attached. You can find it at the bottom of this post.

First, the database…

So, as I said, I started with a SQL Azure database.

You connect to a SQL Azure database using a regular connection string just like any other database, so it will be a no-brainer for you to read this and apply it to a SQL Server on premises or even a MySQL or an Oracle database.

My database is a simple schema. It’s just a table of a few attractions that one will find on the island of Kauai, Hawaii and one related table of categories those attractions fall into (i.e. waterfall, scenery, flora, etc.). Here’s a diagram…

image

(my diagram by the way was done using asciiflow.com… very geeky indeed)

In the attached zip file, you’ll find KauaiAttractionsAzureScript.sql that you can use to create this database on your own Azure (or local if you’d rather) instance. Just create the database first and then run the script in the context of your new database. If you want to run through this whole exercise connecting to your own database, however, I would highly recommend it. It would be good practice.

Next, setting up the solution…

Follow these mundane steps to get over the snoozer that is creating projects, adding references, and importing packages…

  1. Create a new solution in VS2012
  2. Add a new Windows Class Library using C# (call it SweetStack.Entities)
  3. Add a new WCF Service Application using C# (SweetStack.Service)
  4. Add a new Cloud project using C# (SweetStack.Cloud)
  5. Add a new Unit Test Project using C# (SweetStack.Tests)
  6. Add a new Navigation App for JavaScript Windows Metro style (SweetStack.Metro)
  7. Add a reference to SweetStack.Entities to the .Service and the .Tests projects
  8. Add the .Service project as a web role to the .Cloud project
    1. In the .Cloud project
    2. Right click Roles
    3. Add | Web Role Project in Solution…
    4. Choose the .Service project
  9. Add the latest version of Entity Framework (currently 5.0.0-rc) to the .Entities, .Services, and .Tests projects
  10. Add the latest version of Microsoft.Data.Services (currently 5.0.1) to the .Services project

Next, creating the .Entities project…

We have our database already in place, and now we want to create an Entity Framework context that will allow us to access our database using code.

Instead of creating an EF model (.edmx file), we are going to reverse engineer the database to POCO classes. Why? Because it’s rad. That’s why. First thing you need to do is install the Entity Framework Power Tools Beta 2 (from Tools | Extensions and Updates in VS2012).

Once that is done, you can right click on your .Entities project and choose Entity Framework | Reverse Engineer Code First. Then enter your connection string information. Remember to check the “Remember my password” box so that it will save your credentials into your connection string for later.

So the tooling should have created a bunch of .cs files in your .Entities project. You not only get POCO classes for each of your database tables, you also get one for the context. That’s the one that derives from DbContext. You also get a folder with a map file for each entity.

All of this is beautiful and I’ll tell you why. You now have a direct 1:1 relationship between your code and your database, but you also have the complete freedom to modify the mappings so that the two don’t necessarily match. If your data architect, for instance, called the database table “first_name” and you’d rather that be called FirstName in your code, then just change that property but keep the mapping to “first_name”. You can even ignore certain properties or add new ones that don’t have a mapping. Furthermore, classes that DO have database mappings can be mixed with other classes that do NOT have mappings. It’s all up to you.

Next, let’s test it…

It’s hard to see a Windows class library work without writing a test for it. In the .Tests project write a simple test that looks something like this…

[TestMethod]
public void TestMethod1()
{
    var context = new SweetStack.Entities.Models.KauaiAttractionsContext();
    Assert.IsTrue(context.Attractions.Any());
}

Before you can run the test, copy the <connectionstrings> element from the app.config, create a new app.config in the .Tests project (right click Add New Item…), and then paste the <connectionstrings> element into the app.config for .Tests.

That test should pass if you haven’t mucked anything up already.

Next, time to create the .Service…

This one just FEELS like it’s going to take a while. Low and behold, however, I bet I could do it in less than 37.5 seconds (not that I’ve timed myself). Do this…

  1. Delete (from the .Service project) the IService1.cs and Service1.cs files that you got for free (even though you didn’t ask for them :)
  2. Right click the .Service project and add a new item… add a WCF Data Service called Entities.svc
  3. Once your file is created, check out the class name and see how it derives from DataService<T> but the T is undefined. Fill that in with SweetStack.Entities.Models.KauaiAttractionsContext
  4. Now uncomment the line in the InitializeService method that says SetEntitySetAccessRule and in the quotes just specify an asterisk (“*”). You can change the EntitySetRights.AllRead to .All if you like, but we won’t be writing any data in this tutorial anyway, so it doesn’t matter so much.
  5. Copy the <connectionstrings> element from the app.config of the .Entities project into the web.config of your .Service project
  6. Put your hands down… you’re done!

Set your .Service project to the startup project and run it. You should get a browser that looks like this…

image

Note: if you get a list of files instead, just click on the Entities.svc first.

Next, we let’s see what we’ve got…

What you’re looking at there is a GEN-YOU-WINE OData feed. That’s exciting. OData rocks. Not only do you get all of your entities extended through OData, but you get type information about them and you get their relationships with each other. Also, you can ask an OData feed for XML or for JSON and it will say “Yes, sir/ma’am.”

Fire up Fiddler and hit that service root URL appending each of the following and see what you get for responses (also add “Accept: application/json;odata=verbose” to the headers in Fiddler to request JSON). Issue the following commands against your service and behold the results…

{root service URL}?$top=1 selects just the first entity.
{root service URL}?$select=Id,Name fetches all entities, but projects them to lighter JSON objects by only including the Id and Name properties.
{root service URL}?$filter=Location%20eq%20'North' gives you entitites that have a Location value of “North”.
{root service URL}?$filter=substringof('Falls',Name)%20eq%20true” gives you only entites with the word “Falls” in their Name
{root service URL}?$select=Name&$orderby=Name selects just the Name property and sorts it
{root service URL}?$expand=Category this one brings in the related Category entity… this a significant point and a differentiator from flat GET web service operations. Look at the JSON message in the response with and without this URL property.

If that doesn’t turn your crank then you should check your Geek card… it might be expired.

Next, we go Metro…

We’re ready to consume our data. We’re going to be working here with an HTML/JS Metro application which makes it reasonable brainless to consume JSON. Here we go…

I had you create your Metro app from the navigation template, so you should have a pages folder (assuming your using Visual Studio 2012 as opposed to Visual Studio 11). In there you have home.html, home.css, and home.js. Those three files are all we’re going to concern ourselves with for now.

In the .html file, you need to create a ListView and define an item template and a header template (because we want our items to appear in groups). Here’s what that would look like…

<div id="itemtemplate" data-win-control="WinJS.Binding.Template">
    <div data-win-bind="onclick:click">
        <img data-win-bind="src:ImageUrl" />
        <div data-win-bind="innerText:Name"></div>
    </div>
</div>
<div id="headertemplate" data-win-control="WinJS.Binding.Template">
    <div data-win-bind="innerText:category"></div>
</div>
<div id="list" data-win-control="WinJS.UI.ListView"></div>

Then in the .css file add the following so that our images are the right size and our ListView is tall enough to show two rows…

.homepage section[role=main] {
    margin-left: 120px;
}

.homepage #list {
    height: 100%;
}

    .homepage #list img {
        width: 280px;
        height: 210px;
    }

Finally, in the .js file we need to add just a little bit of code. I’ll just drop it all on you and then explain each section. Put this inside the page’s ready method…

var attractionsListGrouped = new WinJS.Binding.List().createGrouped(
    function (i) { return i.Category.Name; },
    function (i) { return { category: i.Category.Name }; }
);

var list = document.querySelector("#list").winControl;
list.itemDataSource = attractionsListGrouped.dataSource;
list.itemTemplate = document.querySelector("#itemtemplate");
list.groupDataSource = attractionsListGrouped.groups.dataSource;
list.groupHeaderTemplate = document.querySelector("#headertemplate");
            
WinJS.xhr({
    url: "http://onesweetstack.cloudapp.net/Entities.svc/Attractions?$expand=Category",
    headers: {"Accept":"application/json;odata=verbose"}
    }).then(function(xhr) {
        JSON.parse(xhr.response).d.forEach(function (i) {
            i.click = function (args) { WinJS.Navigation.navigate("/pages/attraction/attraction.html", i); }
            i.click.supportedForProcessing = true;
            attractionsListGrouped.push(i);
        });
    });

The first part (var attractionsListGrouped…) creates a new WinJS.Binding.List that groups the items by their .Category.Name. This necessitates that we bring our Attraction entities down with that $expand property included to get the related Category, but that’s easy so we worry not.

The next part imperatively sets the item and header templates and the data sources of both the items and the groups. This can be done before our list has even been populated with any items. In fact, we need to do it that way because the call we make to get the items is asynchronous and we need that list that we’re binding to to exist before we even get back from that call.

The last part is the xhr call. You can see the syntax. The xhr expects an object within which we’re specifying the url and a custom header. The function we pass in to the subsequent .then is going to run after we get back from the xhr call. At that point, we can look at the response, parse it as JSON, and then for each item, push it into our list. This list is a WinJS.Binding.List which means that it is essentially observable and will tell the UI when updates have been made so it can change accordingly. So when our items are fetched and filled in, the user will see them pop into the ListView in his view.

Tangent about application/JSON;odata=verbose…

Remember how we added application/JSON;odata=verbose to our headers for the xhr call? Why would we do that? It’s because we’re using the prerelease version of WCF DS, and the existing OData JSON syntax has been dubbed “verbose” to make room for some awesome new methods for expressing rich, typed, interrelated OData while keeping the payload light, light, light. More on that at a later time.

Conclusion

Attached you’ll find the complete source code. Hope it helps you learn Windows 8 development and I hope you get your first app done soon and are rewarded with huge royalty checks :)

And that does it for this walk through. It was a marathon post, so if you’re read this far email me your mailing address and I’ll send you a gift in the mail. I’m betting I won’t be troubled to send too many gifts :) (offer expires the end of June 2012)

OneSweetStackLive.zip (9.90 mb)

Tags: , , , , , , , , , , , , , , ,

C# | CSS | JavaScript | Visual Studio | Windows 8

How to do Semantic Zoom in an HTML/JS App

by Jeremy Foster 13. June 2012 10:17

Semantic Zoom is super easy, but even the easy things can use some conceptual explanation and examples to clarify them. Rest assured that once you see it, you’ll go “Ah! That won’t be a problem then.”

If you use XAML/C# to make your Metro apps, then you should check out Jerry Nixon's post on semantic zoom.

So, I’m going to be talking about Semantic Zoom. You know what that is right? It’s different from optical zoom. It’s a Windows 8 differentiator and it’s really helpful. It’s a way of zooming out of some information and making it easier to orient and easier to consume. Optical zoom just scales everything. Semantic zoom shows a different logical version of the same list.

Any given list in a Windows 8 screen may be 3 or 4 or 5 screens worth of horizontal information, right? Well, it’s not hard to pan that far, but it’s not always easy to really see what your scope is when it’s on 4 screens. When a user semantically zooms out, he is hoping to get oriented with your data. He is hoping to rise up so he can understand and/or so he can dive back in at just the right place.

I’m going to provide an example here. My example is a list of attractions in Kauai. Each has a category property - things like Flora, Scenery, Waterfall, etc. I will use these categories to group my list, but with the grouping and all of the content I want to show, the list is about 4 screens wide…

image

This might be a good scope of data for this view in my app, but at the same time it might be too much to expect a user to be able to consume in a glance. So, we implement semantic zoom. When the user pinch zooms, we want to show them something like this…

image

This is not very stylish, I know, but it serves to make the point. We want to indicate in much less horizontal space (and hopefully on a single screen) what our data contains. In this case, we’re showing the categories. We could get quite creative with what we show here. The concept is to logically expand our scope to orient the user.

Now when the user chooses the Waterfall tile, he’ll be semantically zoomed back in and will be taken directly to the waterfall section. The user can also zoom back in using a stretch zoom gesture (two fingers on the screen and then moved further apart).

Let’s move on to how to implement this. It’s by no means rocket science. Unless of course you’re building an app for… er… rocket science.

Start off with a blank Metro application. First thing you’re going to need is the data.

In your default.js file, add an onready function like this…

app.onready = function (args) {
    
};

And then inside of it add your data like this…

var attractions = [
    { name: "Fern Grotto", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/98/super/fern_grotto-kauai-attraction.JPG", description: "Only accessible by boat or Kayak, the fern Grotto is located about two miles up Kauai’s Wailua River, the only navigable river in the State of Hawaii." },
    { name: "Hanalei Valley Lookout", category: "Scenery", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/51/super/hanalei-valley-lookout-kauai-attractions-3.jpg", description: "The Hanalei Valley is an enchanted site charmed with the likes of countless waterfalls, rainbows, fields of taro and hidden treasures waiting to be explored." },
    { name: "Hanapepe Swinging Bridge", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/93/super/843726541306971801.jpg", description: "Located in old town Hananpepe a Historical sight made up of an eclectic group of galleries and shops. Home to Friday night Art walk." },
    { name: "Kalalau Lookout", category: "Scenery", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/94/super/3075381091306977440.jpg", description: "The Kalalau lookout stands at 4,00 feet above sea level and gives you a peek at a valley that as late as the 1920's still was the home to residents who farmed crops there. The only way into the valley is by foot along the Kalalau Trail or by boat." },
    { name: "Kauai Coastal Path", category: "Coastline", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/100/super/kauai-coastal-path-kauai-attractions.JPG", description: "Kauai Coastal Path is a scenic and and safe place to walk, run or bike while taking in the beautiful scenery of Kauai's East Side." },
    { name: "Keahua Arboretum", category: "Flora", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/95/super/keahua-arboretum-kauai-attractions-5.JPG", description: "The Keahua Arboretum is planted with native and introduced plants by the University of Hawaii and is used as an outdoor classroom to students and visitors. Cool off in the cold mountain spring water and enjoy lunch at one of the picnic sites." },
    { name: "Kilauea Lighthouse National Wildlife Preserve", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/49/super/kilauea_lighthouse_national_wildlife_preserve-kauai-attraction.JPG", description: "Kilauea Point National Wildlife Refuge started in 1985 by the U.S. Fish and Wildlife Service is marked by its towering lighthouse. The ocean cliffs and tall grassy slopes of a dormant volcano provide a protective breeding ground for many Hawaiian seabirds" },
    { name: "Koloa Landing", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/99/super/koloa-landing-kauai-attractions-2.jpg", description: "Once one of the largest deep water whaling ports in Hawaii, Koloa Landing is now a popular location for shore dives." },
    { name: "Lawai International Center", category: "Other", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/110/super/lawai-international-center-kauai-attractions.JPG", description: "Lawai International Center and the 88 Shrines are located on the ancient site of Heiau where Hawaiians once came for healing." },
    { name: "Menehune Fishpond", category: "Other", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/48/super/menehune-fishpond-kauai-attractions.JPG", description: "Menehune Fish Pond is located just above the Nawiliwili Harbor. The Menuhune Fish Pond, Alekoko got it's name from the legend that a small race of people known as menehune built these ponds 1,000 years ago overnight." },
    { name: "Napali Coast", category: "Coastline", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/82/super/napali-coast-kauai-attractions.jpg", description: "The Napali is a fifteen mile stretch of coastline starting on the north shore at Kee beach and ending on the west side at Polihale beach. This rugged coast will leave you breathless as you gaze upon the he razor sharp cliffs that rise sharply from sea to " },
    { name: "Opaekaa Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/88/super/opaekaa_falls-kauai-attraction.JPG", description: "Opaekaa Falls can be seen from the scenic lookout along Kuamoo Road in the Wailua Homesteads. " },
    { name: "Spouting Horn", category: "Coastline", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/86/super/spouting-horn-kauai-attractions-1.JPG", description: "Spouting Horn Beach Park is a delightful lookout where you can watch a blowhole spout a plume of sea water into the air." },
    { name: "Tree Tunnel", category: "Flora", location: "South", imageUrl: "http://www.kauai.com/photos/kauai/point/91/super/tree-tunnel-kauai-attractions.JPG", description: "The beautiful canopy of eucalyptus trees line Maliuhi Road, the gateway to Kauai's sunny side and the towns of Koloa, and Poipu." },
    { name: "Wailua Falls", category: "Waterfall", location: "East", imageUrl: "http://www.kauai.com/photos/kauai/point/50/super/wailua_falls-kauai-attraction.JPG", description: "This 140 foot waterfall appears on many postcards, print and media collections and was used as the opening scene for the 1970’s Television series Fantasy Island." },
    { name: "Waimea Canyon", category: "Other", location: "West", imageUrl: "http://www.kauai.com/photos/kauai/point/83/super/waimea-canyon-kauai-attractions-2.JPG", description: "Waimea Canyon State Park is the largest canyon in the Pacific and will undoubtedly capture your gaze, with its 10 mile long stretch at a mile wide and measuring more than 3,500 feet deep." },
    { name: "Wet and Dry Caves", category: "Other", location: "North", imageUrl: "http://www.kauai.com/photos/kauai/point/111/super/wet-and-dry-caves-kauai-attractions.jpg", description: "Waikanaloa & Waikapalae Wet Caves are located off the the main road in the Haena State Park and are easy to get to. The Waikanaloa Cave is not for swimming. The Waikapale cave is located a a little further up the road and involves a quick hike to the swim" },
];

And then you need to turn that simple JavaScript array into a Binding List so you can bind to it. Like this…

var attractionsList = new WinJS.Binding.List(attractions);

And then you group that list like this…

var attractionsListGrouped = attractionsList.createGrouped(
    function (i) { return i.category; }, //group key
    function (i) { return { category: i.category }; }  //group
);

And there’s that.

Now, let’s visit your HTML file (default.html).

You’ll need your actual ListView…

<div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>

And you’ll also need a template and a header template…

<div id="headertemplate" data-win-control="WinJS.Binding.Template">
    <div data-win-bind="innerText:category"></div>
</div>
<div id="zoomedintemplate" data-win-control="WinJS.Binding.Template">
    <div>
        <img class="item-image" data-win-bind="src:imageUrl" />
        <div data-win-bind="innerText:name"></div>
    </div>
</div>

And then you need to bind the ListView to your data, so go back to your default.js file and after the var attractionsListGrouped statement, add this…

var zin = q("#zoomedinlist").winControl;
zin.itemDataSource = attractionsListGrouped.dataSource;
zin.groupDataSource = attractionsListGrouped.groups.dataSource;
zin.itemTemplate = q("#zoomedintemplate");
zin.groupHeaderTemplate = q("#headertemplate");

Now you should have a working list, and all we have to do is add the semantically zoomed out version and the semantic zoom control itself.

So, on the default.html page, add the semantic zoom control and the zoomedoutlist to the list you already have like this…

<div data-win-control="WinJS.UI.SemanticZoom">
    <div id="zoomedinlist" data-win-control="WinJS.UI.ListView"></div>
    <div id="zoomedoutlist" data-win-control="WinJS.UI.ListView"></div>
</div>

(note that last code should be pasted over the existing zoomedinlist since we already had that there)

Then, that zoomedoutlist needs some data binding, so we go back to the default.js and add this…

var zout = q("#zoomedoutlist").winControl;
zout.itemDataSource = attractionsListGrouped.groups.dataSource;
zout.itemTemplate = q("#zoomedouttemplate");

OKAY STOP. Let me explain what’s going on here. Quite simply, we’re just adding two different ListView controls with their own data bindings (that happen to be based on the same data, and then we are wrapping both of those up with the WinJS.UI.SemanticZoom control.

Keep in mind, that there are no constraints necessarily on what can comprise those two lists. You, the developer, are responsible for making sure that your semantic zoom control makes good sense for the user.

Now, please notice that the data source for the zoomed in list is a grouped list of attractions, while the data source for the zoomed out list is a list of groups. Thanks why we get the categories for our zoomed out tiles.

I added a couple of classes in the templates that I had you paste into your HTML, so if you add the following style rules to your default.css file, then that should make everything look sensible…

.item-image {
    width: 280px;
    height: 210px;
}

.sz-category {
    width: 200px;
    height: 200px;
    background-color: green;
    color: white;
    font-weight:bold;
    font-size: large;
    padding: 10px;
}

And that should do it. Leave a comment if this was helpful. Actually, leave a comment if it wasn’t helpful too. :)

Happy zooming.

Tags: , , , , , , , , , , , , , , , ,

CSS | HTML | JavaScript | Windows 8

When to Use ViewBoxes and FlexBoxes

by Jeremy Foster 12. June 2012 12:11

HTML and CSS is great, but there’s at least one thing that has driven web designers mad for ages - layout. We used to use tables and it worked. We knew their weaknesses, but they worked. Then we were told that tables are for tabular data and div elements are for layout, but divs are wretched creatures. To set divs next to each other one had to float them, but then when finished floating had to be explicitly turned off - argh. Also, divs had no notion of filling vertical space or of controlling the vertical placement of anything within it.

So a myriad of web designers resorted to absolute positioning, browser hacks, jQuery UI positioning, or some other means just to get things to go where they ought.

Enter Windows 8.

Windows 8 allows us to design our Metro style apps using HTML and CSS. In doing so, however, it the CSS standards and Microsoft have given us some facilities to finally place things where we want them.

It’s not obvious how everything works though so let me give you a boost. If you start with a Fixed Layout Application (for the record, I think it should be called the Flexible Layout Application) project template you get the right stuff automatically, but here’s an explanation so you have the concept as well.

We’re dealing with two entities here: the WinJS.UI.ViewBox control and the -ms-flexbox css property value (for the display property).

WinJS.UI.ViewBox

The purpose of the ViewBox is stated in the documentation. It says that it “Scales a single child element to fill the available space without resizing it. This control reacts to changes in the size of the container as well as changes in size of the child element. For example, a media query may result in a change in aspect ratio.”

The first thing I had a hard time wrapping my head around was the overlap between a ViewBox and a FlexBox. Then I discovered that there really isn’t any. The ViewBox control is quite simple. It scales the content that it contains but maintains it’s aspect ratio.

It works like this…

image

Note that it does not work like this…

image

In other words, as it says in the documentation, it scales the contents, but it keeps their proportions.

And that’s really the end of it. The ViewBox serves this one purpose.

Flexbox

Now it’s time to talk about the flexbox. This is not a WinJS control, but rather an implementation of a CSS3 property. It’s not quite a standard property yet because all of the browsers are still implementing it with vendor specific properties and values, but it’s close. For Windows 8, we specify a display property with a value of -ms-flexbox to indicate flexbox layout.

The purpose and scope of the flexbox is a bit bigger than the ViewBox. Here’s what the W3C spec for the CSS Flexible Box Layout Module says “In the flexbox layout model, the children of a flexbox can be laid out in any direction, and can "flex" their sizes, either growing to fill unused space or shrinking to avoid overflowing the parent. Both horizontal and vertical alignment of the children can be easily manipulated. Nesting of these boxes (horizontal inside vertical, or vertical inside horizontal) can be used to build layouts in two dimensions.”

So, like the ViewBox, we still have the concept of the container’s content changing in size to fit the container, but this has more to do with a collection of child items.

Additionally, the flexbox offers a lot of properties to specify how it’s children are laid out. A quick glance in Blend at the CSS properties on a div in the Flexbox category will enumerate them for you…

image

Notice first the -ms vendor specific prefix as I mentioned.

To give a thorough description of the possibilities with these properties, I’d be duplicating what’s already done quite nicely on the flexbox page on w3.org, so just go there and read the nitty, gritty detail.

Differences

The ViewBox is a WinJS control, whereas the flexbox is a CSS property.

The ViewBox always acts on a single child item, but the flexbox can act on multiple child items.

The ViewBox itself changes size to fit it’s container as a core feature. The flexbox can be told to scale to 100% either in width or height, but it doesn’t have to.

The ViewBox does not extend control over the alignment and scale modes of it’s contents, but always does the same thing - scales the child item without changing it’s proportion.

All Together Now

Now that you know how different these controls are, consider them together. If you put a flexbox div inside of a ViewBox, you get a really effective layout tool. Try this for your HTML…

<body>
    <div data-win-control="WinJS.UI.ViewBox">
        <div class="flexy">
            <div class="item">A</div>
            <div class="item">B</div>
            <div class="item">C</div>
        </div>
    </div>
</body>

With this as the CSS…

.flexy {
    -ms-flex-align: center;
    -ms-flex-direction: column;
    -ms-flex-pack: center;
    display: -ms-flexbox;
}

.item {
    height: 200px;
    width: 200px;
    border:solid 1px;
    font-size:9em;
}

What you have now is a flexbox that fills its area well. Look at these simulator screenshots so you can see what this would look like…

imageimageimageimage

XAML is unarguably the most powerful layout engine I’ve ever seen, but I really don’t feel like there’s too much in HTML/CSS that we’re missing now with additions like this. It’s rather empowering.

Happy layouts!

Tags: , , , , , , , , , ,

CSS | Windows 8

The Counter Principles of Metro Style Design

by Jeremy Foster 30. May 2012 10:36

Likely you’ve read the Metro style design principles, but you haven’t seen the counter principles yet (because I made them up). Here we go...

1. Show Shame in Mediocrity

To really show shame in mediocrity, just look at about 80% of the apps in any major app marketplace. These apps may get a users attention with a catchy title or a promise to solve some problem, but then they fail to add any value to anyone’s life. Even if they are not devoid of functional value they fail to provide any user joy.

  • Ignore the little things
  • Do something different in every little user interaction so you can keep them on their toes
  • Embrace chaos
  • Deviate slightly from the grid so the user knows something is wrong even though that can’t see it

2. Flow Like Peanut Butter

To be clear, peanut butter doesn’t flow. Even creamy peanut butter doesn’t flow. To meet this counter principle, perform actions synchronously, use while loops that peg the processor, and only use the UI thread.

  • Add some offset between the user’s finger and the registered touch point
  • No transitions or animations... all straight cuts
  • Add boring graphics and boring interactions.
  • Embrace lag and jitters

3. Be Faux Analog

It’s 2012, but give the user a solid 1994 experience by rendering an actual real-life scene and hope they’ll figure out which drawer their word processor is in. Even though there’s no actual need for a spiral binding, let’s add one. It’s nostalgic.

  • Show a desk or a lobby or some other loose analogy to your navigation model
  • Firmly draw your limits at real life paradigms and scenarios
  • Expand on the success of Microsoft Bob©

4. Do Less With More

Pack that screen. You have millions of pixels at your disposal. You can use some for navigation, some for commanding, and if there's room left over you can even include your user’s content.

  • Assure that users can orient themselves to your views within 7.5 minutes
  • Adhere to a strict 45 button limit per view
  • Give users a sense of adventure as they discover your application

5. Die Alone

  • Assume the user is only concerned with doing whatever it is that your app does.
  • Assume they don’t have friends to share your content with.
  • Assume they don’t need to find anything of your content
  • Assume the user what’s to do one thing at a time... always... ever... only

Tags: , , , , , , , , , , ,

Windows 8

Windows 8: Top 10 Reasons Why I Choose HTML5 Over XAML

by Jeremy Foster 23. May 2012 10:26

My colleague and friend Jerry Nixon recently wrote an article on the top 10 reasons why he chooses XAML over HTML5 and it begged me for a reply. Alas, here it is...

Following are the top 10 reasons why I’m in the HTML/CSS/JS space right now.

I should qualify. I completely adore C# and XAML. I geek out on the nuances of the C# language, lambda expressions give me joy, and LINQ is like dreams and starlight. But that’s not where I am right now. I’m moving on but not moving away. I want both bullets in my belt... the sheer power of C# and the wit and fancy of JavaScript.

More qualification. I love JavaScript and at the same time I hate JavaScript. Sometimes it makes me feel like a coding cowboy and other times like I’m in its gallows.

So here we go...

1. Skill Ready

I and about a kazillion other people in the world have gathered a ton of experience on the HCJ stack. Websites became applications as some point, and they became essential in the enterprise. I would guess that the web stack has drastically more developers than any other stack... but that’s a guess.

2. Triptych

HTML, CSS, and JavaScript form what I like to call the happy triptych. Instead of separating code into two roles, HCJ has three. HTML defines the structure, CSS defines the layout and style, and JavaScript defines the logic. This makes things like modifying the layout and style for different view states or devices as simple as swapping out the style sheet.

3. Dynamic

I know that C# has the DLR and I’ve used it in numerous real scenarios, and it’s some awesome functionality added to the language. JavaScript, however, is truly dynamic. If I want to add a property to my app like lastLaunched, I just type app.lastLaunched = “5/1/2012” and voila I have a new property. If I want to add a function called detectLastLaunched, I just type app.detectLastLaunched = function() { ... }. That’s way cool.

4. JSON

JavaScript has JSON. I know that C# can speak JSON too, but not like JavaScript. JavaScript and JSON go together like peas and carrots.

5. Light

JavaScript is light. Super light. The absence of some of C#’s heavy artillery (I’m thinking polymorphism, inheritance, type safety, etc.) leaves it light and agile. The fancier things like inheritance and even asynchronicity are implemented as patterns instead of as language features. This means they’re not baked in so they can be adapted to suit.

I was newing up some sample data in both languages the other day. I had to declare all of my types in C# and then even with object and collection initializers, the code to create the sample data was quite large and repetitive. In JavaScript on the other hand, it’s a matter of declaring a variable and setting it with very terse object initializer syntax... thing of beauty.

Just compare the default Metro style Grid Application in XAML/C# and then in HTML/JS and you’ll see how light JavaScript is.

 

6. Libraries

Again, there are a ton of web stack developers out there and consequently there are a ton of web stack libraries and helpers. Bing something like “javascript face detection” and you’ll find an open source library that’s ready to go. Glance at microjs.com to see what I mean about JavaScript library support.

7. Query Selection

In XAML, it’s easy enough to give a control an ID and then select it in the code. But how do you select all of every third paragraph, the third element in the grid, or something like that. The answer is imperative code. There’s no part of the object model that you can’t access, but with query selectors in CSS and JS, you can use simple strings like “div#myDiv p:nth-child(3n)” to select every third paragraph in the div with the ID of myDiv.

8. CSS

CSS is amazing. With a collection of style rules, I can style, animate, layout, add images, position things, and a ton more. With declarative CSS code I can make the same HTML view look entirely different. Style rules cascade down to the eventual screen element and allow a developer to set a style globally and then override that style locally given the need.

There’s a JS library called LESS that extends CSS’s capabilities and allows me to set style variable and even do variable math. So I can set the base color of my app to red and then create a number of derived colors (darker or lighter for instance). That way, the change of a single color variable will result in a complete change to my app’s color palette.

9. Blend

The nature of HTML/JS apps means that Blend for Visual Studio can dynamically execute the application while you’re designing it. Expression Blend (the XAML designer for classic Windows apps, Silverlight, Windows Phone, etc.) has some robust support for sample data and designer data because it’s not able to drag in the application data at runtime. With Blend, however, when working on a Metro style app using JavaScript, the entire need for sample data goes away. Instead, you look at your real app data... even if you’re pulling it down from the sky (I’m a little tired of the word cloud, so I choose to use the word sky).

10. Name

I live in Seattle. I drink coffee. Fancy coffee. The people that make coffee in this town are insane about their technique, the quality of their bean, and the nanosecond precision of their brew pull. So I’m enjoying JavaScript because it goes so well with the french press of Ecuadorean joe I hold before me.

Sorry, C#. Your name is sharp, but it’s so technical and boring compared to JavaScript.

Nail. Coffin. JavaScript wins hands down! Oh, whatever. It’s all in fun.

Tags: , , , , , ,

C# | CSS | JavaScript | Windows 8 | XAML

Feed Subscribe