Web Development Adventures in a .NET world

By Ola Karlsson

April 2008 - Posts

Semi transparent Silverlight on top of HTML

My last post was about laying Silverlight on top of HTML, using CSS for positioning and ordering of the layers.

However one thing that had me stumped for a bit was how to set the transparency on the Silverlight area. Surely it can't be that hard!?

Lessons learned

In my previous post I mentioned, possibly using the CSS opacity setting on the <object> tag to achieve the goal. Having had a play around, I found that, yes you can do it that way, and it seems to work fine (keep in mind different browsers support it somewhat differently). However there is a much simpler and neater way of doing it.

In the default test page that gets created the <object> tag takes a parameter named background , this gave me the first clue.

SilverlightControlHost

Next I saw Michael Kordahi's example of overlaying SL on top of HTML and got some ideas from how he was doing things, the problem was that he was using the SL 1.0 way of calling up the silverlight using the createSilverlight() in a silverlight.js file etc. So I had to figure out how to translate that into what I was doing, it would seem pretty basic. Michael was passing in the following as part of his javascript call to create the Silverlight object. background:'transparent', isWindowless: 'true'. However passing in those as parameters to my HTML objet tag didn't work.

To make what was a pretty long story short( the long version including me stumbling around trying to figure things out) , here is what I learned.

A. There seems to be some issues with passing in parameters to HTML <object>, I got caught out a few times making changes then refreshing the page and nothing happening (making me think I was doing it wrong), this went on until I found some resources confirming that I was in fact doing it the right way. Once I started closing and restarting the browser between changes, things worked a lot better.

B. The background and windowless attributes seem to be SL2 specific ones. Looking at various resources (including both W3C and Microsoft) covering the HTML <object> tag gave me no information, however eventually I came upon this blog post by Alex Golesh, that briefly talks about the difference in between SL2 and CreateSilverlight(), this post in itself didn't really tell me what I wanted to know but it pointed me onwards and evetually I found my way to the Microsoft SL2 documentation about Instantiating a Silverlight Plug-In. You can tell it's beta documentation but at least it's got some info, I guess this was a lesson learnt, start by looking at the MS documentation, then hit the web.

So, on to the actual solution!

As I said it seems like it should be pretty simple, and guess what, it is! There's two steps, first edit the hosting page, then make the necessary modifications to the XAML.

Step 1 

If you're hosting your SL in a HTML page, set the background parameter to transparent and the windowless parameter to true. Also keep in mind the size, building a full SL app this is usually set to 100% width and height, however if we want to use it together with the HTML, we want to change it to match the actual size of your XAML/Silverlight element.

SL-HTML 
If you're hosting it in a aspx page using the SL2 Silverlight control, you want to do the same adjustments as above, adjust the size, then add the parameters PluginBackground and Windowless.

SL-ASPX

As per usual when working with server controls you can either change things in code as per above or use the properties window as below.
SL-Properties

Step 2

Adjust the opacity/transparency of the XAML, this can be done in a few different ways and they have slightly different outcomes.

Option 1

Setting the opacity of the user control
image
Or on the LayoutRoot element
image 
Gives the following result
image
The thing to notice here is that the opacity setting is inherited by the children of the control it's set on.
Hence both the canvas and the button are effected in both cases.

Option 2

A slightly different and most of the time a probably, a more appropriate way of setting the transparency/opacity, is to set the background of the LayoutRoot, to the hexadecimal representation of a colour and include the alpha transparency.
image
Which gives us the following result, where the background is semi transparent but the button is not affected.
image 

Hope you find this useful, I've definitely found that resources in regards to this seems a bit sparse at the moment. And the ones that are out there can be a bit tricky to find.

Links

Blog post by Malky Wullur on overlaying Silverligth on top of Virtual Earth, very cool.
http://geeks.netindonesia.net/blogs/malky/archive/2008/04/16/route-animation-silverlight-with-virtual-earth.aspx

Post by Alex Golesh on Instantiating a Silverlight Plug-In
http://blogs.microsoft.co.il/blogs/alex_golesh/archive/2008/03/16/silverlight-2-amp-createsilverlight.aspx

Using Silverlight.js
http://msdn2.microsoft.com/en-us/library/cc265155(VS.95).aspx

Instantiating a Silverlight Plug-In (Silverlight 2)
http://msdn2.microsoft.com/en-us/library/cc189089(VS.95).aspx#

HTML Objects
http://msdn2.microsoft.com/en-us/library/ms535859(VS.85).aspx#

Silverlight on top of HTML

A question popped up on the OzSilverlight mailing list regarding how to lay silverlight on top of HTML.

The question was by Stephen Price, who I happen to know from the .Net scene here in Perth, Stephen is something as rare, as a mix between .Net developer and Cartoonist, beside being a nice guy :)

Anyway, he was saying how he'd found plenty of resources on how to lay HTML on top of Silverlight but none about going the other way. As I'd actually been thinking about this anyway, I decided to have a go.

Stephen asked for a step by step walk trough so here we go ;)

First a bit of a anecdote, the first project I created I used the Generate HTML test page etc., I figured as we're just working with Silverlight and HTML I'd keep it simple by just using a HTML page to host the Silverlight (I'd not tried to option before).

The default test page which is created by VS in this mode is hidden in the Clientbin folder, it keeps getting re generated and edited by VS, and I found it a bit annoying to work with. Hence I added a new HTML page to work with, doing this I ran into issues where IE would block the silverlight object because it was unsafe :(

image

I'm guessing this has to do with the fact that this page is run off the file system in the browser rather then trough the inbuilt web server in VS.

Hence I went back and created a new project, I called it SilevrlightOnTop and set it up as a Web Application project, why a application rather then a website? Purely because I know it better and is more comfortable with this style of projects, I'm pretty sure it would work just the same in a Website project.

image

So this gives us the following structure, and as we're just going to work with Silverlight and HTML, I created a HTML test page (which doesn't have all the extra stuff you find in the auto generated test page and we can add just what we need).

image

To start with I'll make a couple of minor changes to the default xaml to make it at least a bit more fun to look at.

image

Next I went to the HTML test page and copied over the "silverlightControlHost" div from the auto generated test page. But took out a couple parameters we don't need.
image

Also I edited the width and height of the object tag to match what I did in my xaml (we don't want the tag to be bigger than needed).
image

Next I add another div, named myContent below the silverlight one with some content, giving me the code and browser view below

image    image

Ok, but they're not on top of each other! Well lets fix that with some funky CSS.

Start with adding the following line of code to the myContent div:image

The "z-index=1" sets the content div to be behind any other objects, then it gets positioned absolutely in the upper left corner and the background colour is set to orange.

Next similarly add the following line to the silverlightControlHost div:image

As the "z-index" is higher then the content div, this div will lay on top, I then just moved it in 100pix from the top and from the left side.

Now if we view our page in a browser the view is quite different

image

Voila, Silverlight on top of HTML!

However, one thing I noticed was that the opacity I tried to set in the xaml, doesn't actually work in the browser so that's something to keep in mind. Update: Thinking about it, we might be able to set the opacity of the HTML objects in CSS, I'll have to try and let you know.

I'm also thinking to follow up on this with a step by step guide on how to get the Silverlight to interact with the HTML page. Say for example a button in the HTML calling up the Silverlight area and a button in the Silverlight to hide it. I'll also post up the code for this if anyone wants it.

But that's for tomorrow night :) Edit: If you're interested in semi transparent Silverlight on top of HTML, I've now made a post purely about that.

Writing a tutorial

If you've keept an eye on my blog you would have seen that I've just put up a two part tutorial/article (part 1, part 2) on how to build a simple animated menu using Silverlight 2, Blend 2.5 and VS 2008.

What you might also have noticed is that I've not been posting very frequently, well let me give you a hint, the two are connected. Writing a tutorial and trying to do it properly is hard work! This was my first attempt at something like this and there where a couple of things I picked up along the way that I thought I'd share.

  • If you're going to include screenshots, get some decent screen capture software, it'll make your life a whole heap easier. A popular and good one seems to be Snagit, the only "snag" (ok that was a cheap one) is that it comes with a price tag. The one I'm using, at least for the moment is Desktop Screenshot Whiz, it doesn't have quite all the fancy features but it's free, easy to use and it gets the job done.
  • Make sure you know what the end product will look like. I.e write the code first, then the write up. I don't know how many times I did a bunch of screenshots and the text to go with them, to then realise, actually that's not they way I want to do it. And then having to go back to redo all the screen shots and changing the text. The tricky thing with this is that when you're writing about step A and taking screenshots, you don't want Step B to be seen. The way I dealt with this in the end was to have two VS solutions, one where I did all the coding and tested things etc. and one for taking screenshots and such, the later one is then the code you publish.
  • Use a tool like Windows Live Writer or similar, it gives you benefits like an easy way to include images and spell checking. I strongly advise against using Word to write your article, I thought I'd have a play with it, and found the formatting of my text and images once I uploaded them to the blog a nightmare to sort out. 

Cheers, and happy coding!

 

Posted: Apr 13 2008, 09:25 PM by ola karlsson | with no comments
Filed under:
Building a simple animated menu with Silverlight 2 - Part 2

After mainly having used Expression Blend to build the XAML for our menu in part 1, it's now time to move back into Visual Studio and actually make some stuff happen :) The Finished result we're aiming for can be viewed here.

Update: I have updated the source code to work with Beta 2 and moved it to a different location, download the code here:  http://www.olakarlsson.com/Downloads.aspx

For this part I use Visual Studio 2008 and C#.

We'll use the solution from part 1, (Silverlight2MenuDemo) so open the solution from part 1 if you've not got it it can be downloaded from here, if you've already got it open in Blend you can right click the solution and select "Edit in Visual Studio".

The first thing we want to do is to edit our XAML a bit, open page.xaml and make the following changes. As with pretty much all XAML objects we could do the following changes with code but to keep it simple I'm going to add the animation objects in our XAML.

Start with adding a Storyboard, a storyboard is the basis of an animation for more in depth information about Animations in Silverlight check out the msdn resources on the topic. Notice how in Visual Studio, unlike in Blend you have full Intellisense for all your XAML, because of this it is often handy to draw up the initial XAML in Blend where you have access to drawing tools etc. but then switch to Visual Studio for fine tuning, just like we've done with our project.


A storyboard is counted as a  resource and is added as seen below. As with all our XAML objects that we wan't to access from code we have to give it an x:Name, I like to name things after what hey do so I've called it "NavigationStoryBoard"

image

Now we need an animation, inside the storyboard add a DoubleAnimation, I've called mine "navAnimation", I choose a DoubleAnimation purely for simplicity sake. As you will see later there are some limitations to what we can do with a Doubleanimation and in a real scenario it might not be the best choice. However for our little demo project it helps to keep things simple :)

image

Next thing we need to do is to tell our animation what object it's supposed to animate, we do this by adding a "Storyboard.TargetName" the object in this case is the red rectangle, which we named mySlider. We also need to tell the animation what property on the target object we're wanting to animate. This is done by adding a "Storyboard.TargetProperty" value, again for simplicity sake we'll just use the objects Canvas.Left property to make the red slider move back and forth between our Menu options. The result should look like below.
image

To finish off our animation we need to give it a duration, i.e. how long will it take for the animation to play. We do this by simply adding a "Duration" value. The Duration below is set to 0.5 of a second.
image

That's it for the XAML, now it's time to move on to the code.

As I'm no expert on XAML animations, I'm not saying that this is the perfect way of doing this but it seems to work ok for what we're doing here.
For controlling the animation, I decided to manipulate the To and From values in code.

The code for manipulating the animation and the storyboard is actually very simple, the somewhat more tricky bit is working out the logic.

The way I decided to tackle it is as follows, I use a number of variables

image

The variables HomePosition,APosition and BPosition are used to hold the values for the menu items positions.

currentlySelectedPosition is used to hold the value of which menu item was last clicked (i.e. where the slider is at the moment).

Next thing is to move inside the Page() code, by default there is a call to InitializeComponent(), this is a method which gives us references to the XAML object we have given x:Names.
If you hadn't noticed, the Page class is marked as partial, the InitializeComponent method is in another part of this class, the code is stored in a file called page.g.cs, the easiest way to find this file is to right click on the InitializeComponent method and select "Go to definition". when viewing this file keep in mind that it's automatically generated and any changes you make in here are likely to get overwritten.

image

Now that we have references to our XAML objects on the page we can set the values for our position variables.

I set the positions of the Menu items by getting the canvas.left value of the Menu option, then adding half of the actual width of the item to get the middle. However to get the middle of the slider to the middle of the menu item, we then subtract half
the width of the slider

HomePosition = (Convert.ToDouble(MenuItemHome.GetValue(Canvas.LeftProperty)) + (MenuItemHome.ActualWidth / 2) - mySlider.ActualWidth / 2);

Next in the Page() method we set up the event handlers we need, for each menu item we need a MouseEnter, a MouseLeave and a MouseLeftButtonUp event handler.

image

And finally we set the default values for the sliders start position, the LeftProperty and the currentlySelectedPosition .
As we're starting with the slider at the "Home" menu item we set it to the HomePosition.

image

Ok so now that we've finished setting things up,it's about time to see something happen!

The code for controlling the animation etc. is pretty much the same for all the menu item event handlers and could be re-factored out into their own methods but to keep it simple and more readable I've just keep the code in the handlers.

Let start with the MouseEnter event, obviously we have one for each menu item, here's the one for B

image

Basically we check that the slider isn't already at our current position, if it's not we move the slider from where it is (currentlySelectedPosition), to the menu item position which is being hovered over.

Lets have look at the MouseLeftButtonUp events, (we could just as easily use MouseLeftButtonDown but the Up event usually gives more of a clicking experience)

image

All we do here is to set the currentlySelectedPosition to the value of the position we're at, HomePosition, APostion and BPosition respectively. As we're clicking the menu item, the animation that runs on mouseEnter will already have completed and we just need to tell the app that the slider now is at position X...

To the final part of our code, the MouseLeave event, again we of course have one for for each menu item, here's the B option.

image 

Pretty much we're doing the same as on MouseEnter but in reverse.
We check that the option we've just left isn't the currently selected one because if it is we don't want to move the slider. However if the option we just left with the mouse, isn't the selected one then we want to move the slider back to the selected menu item.

Note:

This project is done in the simplest way I could think of. I wanted to use something a bit more interesting then a start and stop button to move a shape over the page. The aim is to show, at a beginner level how to use C# and .Net to control an animation in Silverlight 2. Being a simple demo project there are limitations, some of these include the following.

  • Using a basic DuobleAnimation makes the animation quite jerky, to get a smother animation you would probably use a animation with keyframes where you get a lot more control over the motion in the animation.
  • Also of course it's somewhat limiting when all the menu items have to be manually set up and and wired.

Possible enhancements:
As discussed, making the animation smoother.
Refactoring the code to make it more reusable and more dynamic.
Making the menu into a reusable control
Using the Silverlight menu in a .html or .aspx page controlling the html content.

I've been working on some of these enhancements and you can follow the progress here

Finally, the full source code for this demo can be downloaded here, any constructive feedback is more then welcome, hope you enjoyed  :)

Update: I have updated the source code to work with Beta 2 and moved it to a different location, download the code here:  http://www.olakarlsson.com/Downloads.aspx

Sorry for the delay - meanwhile how about that SL 3.0?

As you might have noticed, I've not managed to get the code up for the Menu animation *blushing with shame*.
First I was extremly busy at work then I managed to steal a week away to go on the first proper holiday I've had for years! 

For anyone waiting, I apologiese,the code is done and cleaned up, now I just need to do the write up :)

Meanwhile take a moment and ponder your wishlist for Silverlight 3.0, once you're done head over to Scott Barnes at the Mossyblog Times and submit it :)

Scott is the Product Manager on the Rich Client Platform team,dealing with Silverlight WPF etc. He's recently put out the call for the community's requests for Silverlight 3.0 so here's your chance to tell someone who's actually in a position to do something about it!

 

More Posts