~ubuntu-branches/ubuntu/natty/moon/natty

« back to all changes in this revision

Viewing changes to test/xaml/assorted/tafiti-carousel.js

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-14 12:01:08 UTC
  • Revision ID: james.westby@ubuntu.com-20090214120108-06539vb25vhbd8bn
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
var SJ = null;
 
2
var master = null;
 
3
var carousel = null;
 
4
var imagesLength = 0;
 
5
var selection = 0;
 
6
var unveiling;
 
7
var target = 1;
 
8
var direction = 0;
 
9
 
 
10
function onLoad (sender)
 
11
{
 
12
        SJ = document.getElementById ("slControl").content;
 
13
        master = sender.findName("masterCanvas");
 
14
        console.log ("Loading...");
 
15
        createCarousel ();
 
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");
 
20
 
 
21
        positionImages ();
 
22
        resizeAnimation (272, 92);
 
23
 
 
24
        //fire ();
 
25
        //animateTurn (1.5 / 4);
 
26
        unveil ();
 
27
}
 
28
 
 
29
function animate (animation, handlerName)
 
30
{
 
31
        var sb = carousel.findName (animation);
 
32
        if (handlerName)
 
33
                sb.AddEventListener("Completed", handlerName);
 
34
        sb.Begin ();
 
35
}
 
36
 
 
37
function unveil () 
 
38
{
 
39
 
 
40
    // hide all images
 
41
    //for (var i = 0; i < imagesLength; i++) {
 
42
    //   var image = carousel.findName (generateName ("image", i));
 
43
    //    image.Opacity = 0;
 
44
    //ss}
 
45
 
 
46
    // setup our multi-part animation
 
47
    unveiling = {};
 
48
 
 
49
    unveiling.next = 0;
 
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;
 
54
    
 
55
    animate ("fadeIn", unveilNextSpinStep);
 
56
}
 
57
 
 
58
 
 
59
 
 
60
function animateClockwiseCore() {
 
61
 
 
62
    if (direction == 1) {
 
63
        flipDirection();
 
64
    }
 
65
 
 
66
    // update position based on current selection
 
67
    positionImages();
 
68
 
 
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);
 
72
 
 
73
    selection++;
 
74
    selection %= imagesLength;
 
75
}
 
76
 
 
77
function animateCounterclockwiseCore () 
 
78
{
 
79
    if (direction == 0) {
 
80
        flipDirection();
 
81
    }
 
82
    
 
83
    // update position based on current selection
 
84
    positionImages();
 
85
 
 
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);
 
89
 
 
90
    selection += imagesLength - 1;
 
91
    selection %= imagesLength;
 
92
}
 
93
 
 
94
function flipDirection () 
 
95
{
 
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.
 
98
    
 
99
    direction = direction ? 0 : 1;
 
100
    resizeAnimation(272, 92);
 
101
}
 
102
 
 
103
 
 
104
function animateClockwise () 
 
105
{
 
106
    target++;
 
107
    target %= imagesLength;
 
108
    TurnTowardTarget();
 
109
}
 
110
 
 
111
function animateCounterclockwise () 
 
112
{
 
113
    target += imagesLength - 1;
 
114
    target %= imagesLength;
 
115
    TurnTowardTarget();
 
116
}
 
117
 
 
118
function unveilNextSpinStep ()
 
119
{
 
120
        console.log ("Unveiling next spin step...");
 
121
 
 
122
    if (unveiling.next == imagesLength) {
 
123
        // cleanup
 
124
        //var onCompleted = this.unveiling.onCompleted;
 
125
        //this.unveiling.storyboard.removeEventListener("Completed", this.unveiling.eventToken);
 
126
        //this.unveiling = null;
 
127
        //delete this.unveiling;
 
128
        //if (onCompleted)
 
129
        //    onCompleted(this, null);
 
130
    }
 
131
    else {
 
132
        // unhide the next image
 
133
        var image = carousel.findName (generateName ("image", unveiling.next))
 
134
        image.Opacity = 1;
 
135
        
 
136
        unveiling.next++;
 
137
 
 
138
        // animate one turn
 
139
        animateClockwise();
 
140
    }
 
141
}
 
142
 
 
143
function animateTurn (duration) 
 
144
{
 
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
 
150
        storyBoard.Begin();
 
151
    }
 
152
}
 
153
 
 
154
 
 
155
 
 
156
function positionImages ()
 
157
{
 
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)
 
161
    //        0.5
 
162
    //    0.25   0.75
 
163
    //         0 (or 1.5)
 
164
    // (front of carrousel)
 
165
 
 
166
    // positional offset between images
 
167
    var offset = 1.5 / imagesLength;
 
168
    
 
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);
 
177
        }
 
178
    } else {
 
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);
 
183
        }    
 
184
    }
 
185
}
 
186
 
 
187
function positionImage (imageIndex, position) 
 
188
{
 
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;
 
194
}
 
195
 
 
196
 
 
197
function fire ()
 
198
{
 
199
    for (var i = 0; i < imagesLength; i++) {
 
200
        var sb = carousel.findName (generateName ("storyboard", i));
 
201
        sb.Begin ();
 
202
        }
 
203
}
 
204
 
 
205
function createCarousel ()
 
206
{    
 
207
        console.log ("Creating carousel...");
 
208
    var xaml = 
 
209
        '<Canvas \
 
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> \
 
217
            <Canvas.Resources> \
 
218
                <Storyboard x:Name="fadeIn"> \
 
219
                    <DoubleAnimation \
 
220
                         Storyboard.TargetName="carousel" \
 
221
                         Storyboard.TargetProperty="Opacity" \
 
222
                         From="0" To="1" Duration="0:0:1" /> \
 
223
                </Storyboard> \
 
224
            </Canvas.Resources> \
 
225
        </Canvas>';
 
226
 
 
227
        carousel = SJ.createFromXaml(xaml);
 
228
        carousel.Width = "272";
 
229
        carousel.Height = "92";
 
230
        master.Children.Add(carousel);
 
231
}
 
232
 
 
233
function resizeAnimation (width, height) 
 
234
{
 
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;
 
244
        }
 
245
        else {
 
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;
 
252
        }
 
253
        
 
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;
 
261
    }        
 
262
}
 
263
 
 
264
function onStoryboardCompleted ()
 
265
{
 
266
        console.log ("Completed, will turn toward target");
 
267
        TurnTowardTarget();
 
268
}
 
269
 
 
270
function generateName (keyword, number)
 
271
{
 
272
        return "image_" + keyword + "_" + number;
 
273
}
 
274
 
 
275
function TurnTowardTarget ()
 
276
{
 
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;
 
281
        if (turnClockwise)
 
282
            animateClockwiseCore();
 
283
        else
 
284
            animateCounterclockwiseCore();
 
285
    } else {
 
286
        console.log ("Target matches selection, not turning!");
 
287
    }
 
288
}
 
289
 
 
290
function addImage (imagePath, imageWidth, imageHeight, imageName) 
 
291
{
 
292
        console.log ("Loading %s as %s (%d x %d)", imagePath, imageName, imageWidth, imageHeight);      
 
293
   var xaml =
 
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> \
 
300
            <TransformGroup> \
 
301
                <ScaleTransform Name="' + generateName ("scale", imageName) + '" ScaleX="1" ScaleY="1" /> \
 
302
                <TranslateTransform Name="' + generateName ("translate", imageName) + '" X="0" Y="0" /> \
 
303
            </TransformGroup> \
 
304
        </Image.RenderTransform> \
 
305
        <Image.Resources> \
 
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" \
 
312
                  > \
 
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" \
 
325
                  > \
 
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" \
 
338
                  > \
 
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" \
 
351
                  > \
 
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> \
 
359
            </Storyboard> \
 
360
        </Image.Resources> \
 
361
      </Image>';
 
362
 
 
363
        var element = SJ.createFromXaml(xaml);
 
364
        carousel.Children.Add(element);
 
365
 
 
366
        carousel.findName(generateName ("scale", imageName)).CenterX = imageWidth / 2;
 
367
        carousel.findName(generateName ("scale", imageName)).CenterY = imageHeight / 2;
 
368
 
 
369
        imagesLength += 1;
 
370
 
 
371
 
 
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);
 
377
        }
 
378
}