Archive for February, 2008
The Ken Burns Effect is a popular way of adding emotional appeal to a slide show. It is named after the documentary film director who used it extensively in his series on the American Civil War and Baseball. It is used in the default OS X screen saver. It even makes an appearance as a presentation technique in the 2006 Tom Hanks movie The Da Vinci Code. I thought this would be a fantastic way to showcase photos in the web.
You can see the result with some family photos. I've included photos of all sizes, aspect ratios, and image qualities. This shows off the versatility of the code, but also demonstrates the tradeoffs between quality and speed. I should warn you that image processing in the browser is quite taxing on the client machine. This looks great on my MacBook Pro, but is not so smooth on a less expensive laptop. Flash or Silverlight would be a better choice for client technology.
Fill an array with the URLs of the images to display. You can optionally pass this list to the randomizeList function to shuffle it. Then call the startSlideshow function with this list and the IDs of the two <div> tags. Show source on the example page for more details.
How does it work
The effect uses the setTimeout function to schedule animation steps. It breaks down the animation into fading and panning. The panning is controlled by an object that converts a time index parameter into offset and size. A set of linear equations determine these properties, so that the effect is a smooth transition from one zoom rectangle to another.
The coefficients of these linear equations are determined randomly such that the beginning and ending points are within the bounds of the picture. Because the equations are linear, all points in between are also within bounds. The aspect ratio of the original image is preserved.
The most interesting part of this project was getting the CSS manipulation correct. The images use "position: relative" to indicate that they move relative to their natural resting place. This allows the containing <div> to crop them to fit. But this also means that the images could not coexist within one <div>. Relative positioning is affected by layout, so the second image would be offset by the size of the first.
I've already created a SharePoint view of a picture library using this effect. I plan to package that as a web part and post the code here. I also plan to write code to extract images from Flickr library.
If someone beats me to it, just post a link to your code in the comments. I'll be sure to promote it to a post so that everyone can enjoy.
I like writing posts that end with "Here's my solution". This is not one of them. I'm just documenting this fight so that I can come back to it if I ever find a solution.
I opened up SharePoint Designer to create my new view. I selected "File: New: Page: List View Pages: Document Library View Page Wizard". I selected the picture library to which I wanted to add the new view, and named it "kenburns.aspx".
It starts to go wrong
Here is where the experience deviated from development. When I hit OK on this dialog, it went back to the designer and spun for a while. After a long timeout, it came back with the message "You do not have permission to do this operation." I checked my permissions and confirmed that, yes, I have full control of the entire site.
Going back and forth, I discovered that any change I make to the page causes this error. I can create pages, I just can't edit them afterward.
I started up Wireshark and inspected the traffic. I noticed that there were several duplicate ACKs followed by retries. So packets were getting dropped on the way back to the server. This is probably related to the VPN. I wanted to get this change up tonight, so I didn't have time to fight with the VPN.
So I got clever
I made small incremental changes to the page, but instead of saving it, I copied the contents into a local file, deleted the one I was working on, and then uploaded the copy. After each incremental change and upload, I verified with a browser that the change worked. Tedious, yes, but it worked around the problem.
At least it worked for a while. After a few iterations of this, I could no longer upload the file. Within SharePoint designer, I received the same "You do not have permission to do this operation" message as before. Based on the range of problems that I saw when Googling this phrase, I figured this is SharePoint Designer's way of throwing up it's hands. I even discovered that this error message is a hold over from FrontPage. It's been there a while.
I also tried uploading the file through Explorer. SharePoint does some WebDav magic that makes it possible to connect to a site using "My Network Places: Add Network Place." I navigated to the proper folder and dropped the local copy into it. After a long timeout, I was greeted with "Connection closed by remote server." This is more accurate based on what Wireshark was telling me, but no more helpful. I'm still back in VPN land.
Then I got desperate
I logged into the server via Remote Desktop, opened a command prompt, and executed "iisreset". No help. Then I restarted the box.
Let me pause right here and tell you that I knew at the time that this was a bad idea. I've felt that disconnected, sinking feeling many times before when the machine I'm working on is miles away, I have only a tenuous connection, and decide to let even that connection go. It's like being in a Spielberg movie when the background falls away while the main character is suspended mid-frame.
So I hit "Start: Shut down" (scary enough already) and "Restart". This being Windows Server 2003, I selected an excuse. The remote session was wrenched away from me. And then I waited. And waited.
(fall away and queue eerie violins)
The server still hasn't come back up. I've sent emails asking the next person to go to the office to restart the machine. I'll be in the office tomorrow afternoon, so you can bet I'm installing SharePoint Designer on the server!
Each time I delve into the HTML/CSS world, I am reminded of why I love the Algol-derived languages.
Algol was the ancestor of modern imperative languages like C# and Java. It introduced the concepts of orthogonality and composability to computer language design. Orthogonality is the property of a construct that means it does not intersect with others. There is just one way to express any single idea. Composability is the property of constructs that they can be combined to express larger ideas.
Java is an excellent example of an orthogonal, composable language. Classes, methods, statements, and expressions are all different things (orthogonal). If you want to describe a type of object, you use a class. If you want to describe behavior, it's a method. Through composition, you can describe more complex ideas, like the behaviors of types (class + methods), anonymous types (class + expression), and loops (statement + expressions).
C# relaxes the ideas just a little. For example, a delegate is both a type (class) and a behavior (method). Properties look like members, but act like methods. Since these language constructs serve dual purposes, there is sometimes more than one way to express a simple idea. This was done in the name of convenience, at the expense of language purity.
HTML and CSS
Contrast this with the two ubiquitous languages of the web.
HTML is composable, since you nest elements to construct pages. But these constructs are not orthogonal. An image, for example, could be represented either by an <img> tag or by a <div> with a background-image style. HTML lack of orthogonality is due mainly in part to legacy, as CSS obsoletes elements like <b>.
CSS lacks both composability and orthogonality. Cascading is a limited set of rules, not a true composition mechanism. And several of the attributes interact such that you cannot control one without influencing another.
The "Ken Burns" effect
For the effect, I need to fade from one image to another. So the two images must overlap. In addition, I need to pan and zoom within the frame. This requires that I crop the images. CSS has constructs for both. Unfortunately, they interact.
There are two interrelated concepts at play in the placement of elements on a CSS-based web page: location and layout. Location is the placement of an element itself, whereas layout determines how an element affects the placement of other elements around it.
Position and overflow
The position attribute in CSS affects both placement and layout. The default position is "static", which means that it is entirely under the control of layout. To move an element, you usually set the position to "absolute". This not only gives you control of its position, but also takes it out of the layout equation. For panning, you set position to "absolute".
Now to get the clipping working. We can put the images inside a <div> to define the clip region. Setting overflow of the <div> to "hidden" causes all child objects that fall outside its borders to be cropped.
Unfortunately, for reasons I have yet to comprehend, "overflow: hidden" does not affect child elements with "position: absolute". One attribute controls clipping, while the other controls placement. They should be orthogonal, but they are not.
To solve this problem, I have to select a strange value for position. The position "relative" is properly clipped. However, it combines the ideas of location and layout. Relative positioning is not relative to the containing <div>, as you might expect. Instead, it is relative to the object's resting place as determined by layout. To further confuse the issue, layout proceeds around the object as if it was not moved.
Since I have two images inside the <div> - one fading into the other - the layout of the second is going to depend upon the size of the first. I have to do some extra math based on the size of the first image to adjust the placement of the second. Furthermore, when I switch to a new image, I need to quickly readjust that compensation. I haven't yet determined how to accomplish this without causing some kind of flicker.
Because the CSS attributes are non-orthogonal, I have to solve a multi-variable problem to determine which CSS properties to use to express any given idea. Maybe a plug-in is not so bad.
Derek, Ricky, and I attended the Office Developers Conference in San Jose, CA. There we competed in the national Infusion Sleepless SharePoint Developer's Competition. After the all-night coding competition, we enjoyed the ODC.
At the Bill Gates keynote, I had the opportunity to ask "What is the next killer app?" The answer was that it is not one app as it has been in the past, but the ability to quickly develop custom applications. I agree completely.
We presented our solution during the ODC, with Rock Band playing in the background. Even though we didn't have all the pieces working perfectly, our story really came together. We presented our solution with confidence, and the judges seemed genuinely impressed.
During the keynotes of the second day, they announced the winners. Apparently the judges were impressed, because team Strongbad took the grand prize! We had the rest of the ODC to celebrate our victory, learn even more about SharePoint, and play some Rock Band.
If I ever have the opportunity to compete in this kind of event again, I'll jump at it. The skills I learned and the people I met will stay with me for a long time. Winning is just icing.
I am currently at the Microsoft Office Developer's Conference in San Jose. My team won admission to the conference and the chance to compete in the national Infusion Sleepless SharePoint competition.
We coded all night Saturday into Sunday, then took a bus to San Jose for the ODC. We presented our solution last night in front of a crowd of attendees. We learn the results of the judging this morning at the keynote. I feel our team did very well.
I am learning tons of useful information about the SharePoint product and the ecosystem. The main thing that I was looking for was how to make SharePoint development a repeatable process. I found a breakout session by Andrew Connell that demonstrated exactly that.
Microsoft hasn’t had time to get their tools and documentation in order around SharePoint development, because the explosion of the platform caught them by surprise. But Andrew showed us how Microsoft does SharePoint development internally without strong tool support. Now I believe I can replicate the process.
The highlight of the trip was the Bill Gates keynote. I had the opportunity to ask him "What is the next killer app?" You'll hear his response - and the results of the contest - in the upcoming podcast.
One of the "new" apps that was made available for the iPod Touch is Notes. (Yes, I paid the $20 bounty on them rather than jailbreaking it. I just wasn't worth the drama.)
The app looks like a yellow legal pad. It uses a comic font to simulate handwriting (although my actual handwriting never looked as neat), it has hand-drawn icons for email and trash, and it plays a page turning animation when you switch from one note to another.
As I've said before, this kind of detail sells software. But there is one caveat. The metaphor should never limit the application.
In the early 90's, as software was becoming a commodity in the lives of average people, the graphical user interface was going mainstream. We saw several attempts to make software look like a real thing. The Macintosh and Windows both had desktop metaphors, some online "communities" actually looked like streets with buildings for different destinations, and of course there was Microsoft Bob.
As Alan Cooper tells us in the Myth of Metaphor, software should not limit itself based on the metaphor it chooses. It should be idioms to guide UI design. Idioms are patterns that users come to recognize, even though they have no basis in reality, and may not even be intuitive.
The iPod Touch employs several idioms that we were used to from previous iPods and other software. For example, you can scroll through a list, pick an item, and then the screen slides to the left to reveal a new list. When you go back, the prior list slides back in from the left. The Touch also created some new idioms thanks to its multi-touch screen. Now you can scroll through those lists with a flick of the finger. Most people have to be shown these idioms, but once they see them they apply them everywhere.
The iPod Touch Notes application is not a slave to its metaphor. For example, you can make a note as long as you like. It is not limited to the length of a piece of paper. If it strictly adhered to its metaphor, you would have to turn the page to keep writing. Thankfully, it's one page per note.
But the Notes application does adhere to the iPod Touch idioms. The notes appear in a list, which scrolls with a flick of the finger and slides to the left when you select a note. Notes themselves scroll, even though the "binder" stays fixed at the top of the screen. No physical legal pad in existence could work this way, but that doesn't keep us from understanding it.
The metaphor is only there to give the app a consistent visual design. The idiom gives it its usability.
The Infusion Sleepless Roadshow was an intense weekend of SharePoint training and competition. It was a thrill to participate.
I'd like to thank Infusion for presenting the event, and Microsoft for being a fantastic host. In particular, from Infusion:
And from Microsoft:
And special thanks to my teammates: