10
function onLoad (sender)
12
SJ = document.getElementById ("slControl").content;
13
master = sender.findName("masterCanvas");
14
console.log ("Loading...");
16
addImage ("icon-1.png", 55, 52, "0");
17
addImage ("icon-2.png", 55, 52, "1");
18
addImage ("icon-3.png", 55, 52, "2");
19
addImage ("icon-4.png", 55, 52, "3");
22
resizeAnimation (272, 92);
25
//animateTurn (1.5 / 4);
29
function animate (animation, handlerName)
31
var sb = carousel.findName (animation);
33
sb.AddEventListener("Completed", handlerName);
41
//for (var i = 0; i < imagesLength; i++) {
42
// var image = carousel.findName (generateName ("image", i));
46
// setup our multi-part animation
50
unveiling.callback = unveilNextSpinStep;
51
unveiling.storyboard = carousel.findName (generateName ("image", "0")).resources.GetItem(0);
52
//unveiling.eventToken = unveiling.storyboard.addEventListener("Completed", this.unveiling.callback);
53
//unveiling.onCompleted = onCompleted;
55
animate ("fadeIn", unveilNextSpinStep);
60
function animateClockwiseCore() {
66
// update position based on current selection
69
// It takes 1.5 seconds to animate the carrousel 360 degrees; thus to turn 1 image, run the animation 1.5 / (# of images) seconds
70
var duration = 1.5 / imagesLength;
71
animateTurn(duration);
74
selection %= imagesLength;
77
function animateCounterclockwiseCore ()
83
// update position based on current selection
86
// It takes 1.5 seconds to animate the carrousel 360 degrees; thus to turn 1 image, run the animation 1.5 / (# of images) seconds
87
var duration = 1.5 / imagesLength;
88
animateTurn(duration);
90
selection += imagesLength - 1;
91
selection %= imagesLength;
94
function flipDirection ()
96
// WPF/E doesn't support running an animation in reverse (AutoReverse doesn't cut it).
97
// As a workground, we set up the X coords of the animation based on the current direction.
99
direction = direction ? 0 : 1;
100
resizeAnimation(272, 92);
104
function animateClockwise ()
107
target %= imagesLength;
111
function animateCounterclockwise ()
113
target += imagesLength - 1;
114
target %= imagesLength;
118
function unveilNextSpinStep ()
120
console.log ("Unveiling next spin step...");
122
if (unveiling.next == imagesLength) {
124
//var onCompleted = this.unveiling.onCompleted;
125
//this.unveiling.storyboard.removeEventListener("Completed", this.unveiling.eventToken);
126
//this.unveiling = null;
127
//delete this.unveiling;
129
// onCompleted(this, null);
132
// unhide the next image
133
var image = carousel.findName (generateName ("image", unveiling.next))
143
function animateTurn (duration)
145
duration = Math.round(duration * 1000) / 1000; // only 3 decimal places to keep WPF/E happy
146
for (var i = 0; i < imagesLength; i++) {
147
//var image = carousel.findName (generateName ("image", i));
148
var storyBoard = carousel.findName(generateName ("storyboard", i));
149
storyBoard["Duration"] = "0:0:" + duration; // assumes duration <= 60 seconds
156
function positionImages ()
158
// Images are positioned in a clockwise manner. Position 0 corresponds to 6 o'clock
159
// and increases clockwise to 1.5 as in:
160
// (back of carrousel)
164
// (front of carrousel)
166
// positional offset between images
167
var offset = 1.5 / imagesLength;
169
// The currently "selected" image goes at position 0 (aka 1.5) and
170
// subsequent images are placed counter-clockwise if the direction is
171
// clockwise (and clockwise if the direction is counterclockwise).
172
if (this.direction == 0) {
173
for (var i = 0; i < imagesLength; i++) {
174
var n = (selection + i) % imagesLength;
175
var pos = 1.5 - (i * offset);
176
this.positionImage(n, pos);
179
for (var i = 0; i < imagesLength; i++) {
180
var n = (selection - i + imagesLength) % imagesLength;
181
var pos = 1.5 - (i * offset);
182
this.positionImage(n, pos);
187
function positionImage (imageIndex, position)
189
position = Math.round(position * 1000) / 1000; // at most 3 digits after the decimal so WPF/E doesn't complain
190
carousel.findName(generateName ("animateX", imageIndex)).BeginTime = "-0:0:" + position;
191
carousel.findName(generateName ("animateY", imageIndex)).BeginTime = "-0:0:" + position;
192
carousel.findName(generateName ("animateScaleX", imageIndex)).BeginTime = "-0:0:" + position;
193
carousel.findName(generateName ("animateScaleY", imageIndex)).BeginTime = "-0:0:" + position;
199
for (var i = 0; i < imagesLength; i++) {
200
var sb = carousel.findName (generateName ("storyboard", i));
205
function createCarousel ()
207
console.log ("Creating carousel...");
210
xmlns="http://schemas.microsoft.com/client/2007" \
211
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" \
212
x:Name="carousel" Canvas.Left="100" Canvas.Top="100"> \
213
<Image Source="carousel.png" /> \
214
<Canvas.RenderTransform> \
215
<TranslateTransform x:Name="%translate%" /> \
216
</Canvas.RenderTransform> \
218
<Storyboard x:Name="fadeIn"> \
220
Storyboard.TargetName="carousel" \
221
Storyboard.TargetProperty="Opacity" \
222
From="0" To="1" Duration="0:0:1" /> \
224
</Canvas.Resources> \
227
carousel = SJ.createFromXaml(xaml);
228
carousel.Width = "272";
229
carousel.Height = "92";
230
master.Children.Add(carousel);
233
function resizeAnimation (width, height)
235
for (var i = 0; i < imagesLength; i++) {
236
var animateX = carousel.findName (generateName ("animateX", i));
237
if (direction == 0) {
238
animateX.KeyFrames.GetItem(0).Value = width / 2;
239
animateX.KeyFrames.GetItem(1).Value = 20;
240
animateX.KeyFrames.GetItem(2).Value = width / 2 - 16;
241
animateX.KeyFrames.GetItem(3).Value = width / 2 + 16;
242
animateX.KeyFrames.GetItem(4).Value = width - 16;
243
animateX.KeyFrames.GetItem(5).Value = width / 2;
246
animateX.KeyFrames.GetItem(0).Value = width / 2;
247
animateX.KeyFrames.GetItem(1).Value = width - 16;
248
animateX.KeyFrames.GetItem(2).Value = width / 2 + 16;
249
animateX.KeyFrames.GetItem(3).Value = width / 2 - 16;
250
animateX.KeyFrames.GetItem(4).Value = 20;
251
animateX.KeyFrames.GetItem(5).Value = width / 2;
254
var animateY = carousel.findName (generateName ("animateY", i));
255
animateY.KeyFrames.GetItem(0).Value = height - 10;
256
animateY.KeyFrames.GetItem(1).Value = (height / 2) - 10;
257
animateY.KeyFrames.GetItem(2).Value = 15;
258
animateY.KeyFrames.GetItem(3).Value = 15;
259
animateY.KeyFrames.GetItem(4).Value = (height / 2) - 10;
260
animateY.KeyFrames.GetItem(5).Value = height - 10;
264
function onStoryboardCompleted ()
266
console.log ("Completed, will turn toward target");
270
function generateName (keyword, number)
272
return "image_" + keyword + "_" + number;
275
function TurnTowardTarget ()
277
if (target != selection) {
278
// Determine the best direction to turn the carousel
279
var clockwiseOffset = (target + imagesLength - selection) % imagesLength;
280
var turnClockwise = clockwiseOffset < imagesLength / 2;
282
animateClockwiseCore();
284
animateCounterclockwiseCore();
286
console.log ("Target matches selection, not turning!");
290
function addImage (imagePath, imageWidth, imageHeight, imageName)
292
console.log ("Loading %s as %s (%d x %d)", imagePath, imageName, imageWidth, imageHeight);
294
'<Image x:Name="' + generateName ("image", imageName) + '" \
295
Source="' + imagePath + '" \
296
xmlns="http://schemas.microsoft.com/client/2007" \
297
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" \
298
Canvas.Left="-26" Canvas.Top="-52"> \
299
<Image.RenderTransform> \
301
<ScaleTransform Name="' + generateName ("scale", imageName) + '" ScaleX="1" ScaleY="1" /> \
302
<TranslateTransform Name="' + generateName ("translate", imageName) + '" X="0" Y="0" /> \
304
</Image.RenderTransform> \
306
<Storyboard x:Name="' + generateName ("storyboard", imageName) + '"> \
307
<DoubleAnimationUsingKeyFrames \
308
x:Name="' + generateName ("animateX", imageName) + '" \
309
Storyboard.TargetName="' + generateName ("translate", imageName) + '" \
310
Storyboard.TargetProperty="X" \
311
RepeatBehavior="Forever" \
313
<SplineDoubleKeyFrame KeyTime="0:0:0.00" KeySpline="0.5,0.25 0.5,0.25" /> \
314
<SplineDoubleKeyFrame KeyTime="0:0:0.33" KeySpline="0.5,0.75 0.5,0.75" /> \
315
<SplineDoubleKeyFrame KeyTime="0:0:0.68" KeySpline="0.5,0.25 0.5,0.25" /> \
316
<SplineDoubleKeyFrame KeyTime="0:0:0.83" KeySpline="0.5,0.25 0.5,0.25" /> \
317
<SplineDoubleKeyFrame KeyTime="0:0:1.17" KeySpline="0.5,0.75 0.5,0.75" /> \
318
<SplineDoubleKeyFrame KeyTime="0:0:1.50" KeySpline="0.5,0.25 0.5,0.25" /> \
319
</DoubleAnimationUsingKeyFrames> \
320
<DoubleAnimationUsingKeyFrames \
321
x:Name="' + generateName ("animateY", imageName) + '" \
322
Storyboard.TargetName="' + generateName ("translate", imageName) + '" \
323
Storyboard.TargetProperty="Y" \
324
RepeatBehavior="Forever" \
326
<SplineDoubleKeyFrame KeyTime="0:0:0.00" KeySpline="0.5,0.75 0.5,0.75" /> \
327
<SplineDoubleKeyFrame KeyTime="0:0:0.33" KeySpline="0.5,0.25 0.5,0.25" /> \
328
<SplineDoubleKeyFrame KeyTime="0:0:0.68" KeySpline="0.5,0.75 0.5,0.75" /> \
329
<SplineDoubleKeyFrame KeyTime="0:0:0.83" KeySpline="0.5,0.75 0.5,0.75" /> \
330
<SplineDoubleKeyFrame KeyTime="0:0:1.17" KeySpline="0.5,0.25 0.5,0.25" /> \
331
<SplineDoubleKeyFrame KeyTime="0:0:1.50" KeySpline="0.5,0.75 0.5,0.75" /> \
332
</DoubleAnimationUsingKeyFrames> \
333
<DoubleAnimationUsingKeyFrames \
334
x:Name="' + generateName ("animateScaleX", imageName) + '" \
335
Storyboard.TargetName="' + generateName ("scale", imageName) + '" \
336
Storyboard.TargetProperty="ScaleX" \
337
RepeatBehavior="Forever" \
339
<SplineDoubleKeyFrame Value="1" KeyTime="0:0:0.00" KeySpline="0.5,0.75 0.5,0.75" /> \
340
<SplineDoubleKeyFrame Value="0.95" KeyTime="0:0:0.33" KeySpline="0.5,0.25 0.5,0.25" /> \
341
<SplineDoubleKeyFrame Value="0.90" KeyTime="0:0:0.68" KeySpline="0.5,0.75 0.5,0.75" /> \
342
<SplineDoubleKeyFrame Value="0.90" KeyTime="0:0:0.83" KeySpline="0.5,0.75 0.5,0.75" /> \
343
<SplineDoubleKeyFrame Value="0.95" KeyTime="0:0:1.17" KeySpline="0.5,0.25 0.5,0.25" /> \
344
<SplineDoubleKeyFrame Value="1" KeyTime="0:0:1.50" KeySpline="0.5,0.75 0.5,0.75" /> \
345
</DoubleAnimationUsingKeyFrames> \
346
<DoubleAnimationUsingKeyFrames \
347
x:Name="' + generateName ("animateScaleY", imageName) + '" \
348
Storyboard.TargetName="' + generateName ("scale", imageName) + '" \
349
Storyboard.TargetProperty="ScaleY" \
350
RepeatBehavior="Forever" \
352
<SplineDoubleKeyFrame Value="1" KeyTime="0:0:0.00" KeySpline="0.5,0.75 0.5,0.75" /> \
353
<SplineDoubleKeyFrame Value="0.95" KeyTime="0:0:0.33" KeySpline="0.5,0.25 0.5,0.25" /> \
354
<SplineDoubleKeyFrame Value="0.90" KeyTime="0:0:0.68" KeySpline="0.5,0.75 0.5,0.75" /> \
355
<SplineDoubleKeyFrame Value="0.90" KeyTime="0:0:0.83" KeySpline="0.5,0.75 0.5,0.75" /> \
356
<SplineDoubleKeyFrame Value="0.95" KeyTime="0:0:1.17" KeySpline="0.5,0.25 0.5,0.25" /> \
357
<SplineDoubleKeyFrame Value="1" KeyTime="0:0:1.50" KeySpline="0.5,0.75 0.5,0.75" /> \
358
</DoubleAnimationUsingKeyFrames> \
363
var element = SJ.createFromXaml(xaml);
364
carousel.Children.Add(element);
366
carousel.findName(generateName ("scale", imageName)).CenterX = imageWidth / 2;
367
carousel.findName(generateName ("scale", imageName)).CenterY = imageHeight / 2;
372
if (imagesLength == 1) {
373
// Hook the storyboard's 'Completed' event for just the first image.
374
// We use this event to turn the carousel multiple times.
375
var storyboard = element.resources.GetItem(0);
376
storyboard.AddEventListener ("Completed", onStoryboardCompleted);