轮盘图片转动相关代码

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Net;
  5 using System.Windows;
  6 using System.Windows.Controls;
  7 using System.Windows.Documents;
  8 using System.Windows.Input;
  9 using System.Windows.Media;
 10 using System.Windows.Media.Animation;
 11 using System.Windows.Shapes;
 12 
 13 using System.Windows.Threading; //因为要用到DispatcherTimer等
 14 using System.Windows.Media.Imaging;  //因为要用到BitmapImage
 15 using System.Diagnostics;  //因为要用到Debug
 16 
 17 namespace 图片轮盘转动
 18 {
 19     public partial class MainPage : UserControl
 20     {
 21 
 22         #region  定义变量
 23         private Boolean page_loaded = false;
 24         List<object> angleValues = new List<object>(); //转盘图片在转盘中的角度位置
 25 
 26         private int num_images = 20; //当前图片数量,初始化成20
 27 
 28         private int radiusX = 500;  //设置椭圆的长半径
 29         private int radiusY = 110;  //设置椭圆的短半径
 30 
 31         private int centerX = 460;  //设置椭圆的X坐标
 32         private int centerY = 260;  //设置椭圆的Y坐标
 33 
 34         private double speed = 0;
 35         private DispatcherTimer myTimer;
 36 
 37         private bool main_down = false;
 38 
 39         private DispatcherTimer autoTimer = new DispatcherTimer();
 40         #endregion
 41 
 42         public MainPage()
 43         {
 44             InitializeComponent();
 45 
 46             ResetImagesButton.Click += new RoutedEventHandler(ResetImagesButton_Click); //按下Reset按钮时做ResetImagesButton_Click操作
 47 
 48             myTimer = new DispatcherTimer();
 49             myTimer.Interval = TimeSpan.FromMilliseconds(33);
 50             myTimer.Tick += new EventHandler(myTimer_Tick);
 51 
 52             //Console.WriteLine("call start");
 53 
 54             //设置数量控制滑条的最大值与最小值
 55             numPhotosSlider.Maximum = 180;
 56             numPhotosSlider.Minimum = 10;
 57 
 58             //设置X半径控制滑条的最大值与最小值
 59             radiusSliderX.Maximum = 500;
 60             radiusSliderX.Minimum = 320;
 61 
 62             //设置Y半径控制滑条的最大值与最小值
 63             radiusSliderY.Maximum = 200;
 64             radiusSliderY.Minimum = 100;
 65 
 66             Loaded += new RoutedEventHandler(Page_Loaded);
 67 
 68             BuildImages();
 69         }
 70 
 71 
 72         #region  定义要调用的函数
 73 
 74         #region Page_Load事件
 75         void Page_Loaded(object sender, RoutedEventArgs e)
 76         {
 77 
 78             myTimer.Start();
 79 
 80             //加载默认初始照片
 81             Uri uri = new Uri("images/1.jpg", UriKind.Relative); 
 82             ImageSource imgSource = new BitmapImage(uri);
 83             mainImage.Source = imgSource;
 84             mainImageReflection.Source = imgSource;
 85 
 86             //Debug.WriteLine("Loaded: " + mainImage.Source);
 87             page_loaded = true;  //设置page_loaded标志,表明已经加载了图片了
 88 
 89         }
 90 
 91         #endregion
 92 
 93         #region  Canvas_MouseLeftButtonDown事件
 94         void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 95         {
 96             Canvas c = sender as Canvas;
 97 
 98             //c.Opacity = 0.5;
 99 
100             Rectangle r = c.Children[0] as Rectangle; //取得边框
101             Image img = c.Children[1] as Image;   //取得图片
102             img.Opacity = 0.3;     //设置图片透明度
103 
104             //Debug.WriteLine("canvas down");
105 
106             //加载点击选中的图片
107             mainImage.Source = img.Source;  
108             mainImageReflection.Source = img.Source;
109             //设置边框颜色
110             r.Stroke = new SolidColorBrush(Colors.Red);
111         }
112 
113         #endregion
114 
115         #region 清除所有图片+RemoveImages
116         void RemoveImages()
117         {
118             angleValues = new List<object>(); //重新new一个angleValues
119 
120             for (int i = 0; i < num_images; i++)  //移除所有图片
121             {
122                 Canvas c = this.FindName("imageHolder_" + i) as Canvas;
123                 if (c != null)
124                 {
125                     root.Children.Remove(c);
126                 }
127             }
128 
129         }
130         #endregion
131 
132         #region 加载指定数量的图片+BuildImages
133         private void BuildImages()
134         {
135             int cnt = 1;  //计数
136 
137             for (int i = 0; i < num_images; i++)
138             {
139                 #region 放置图片的Canvas创建与设置
140                 Canvas c = new Canvas(); 
141 
142                 c.Name = "imageHolder_" + i;
143                 c.Width = 100;
144                 c.Height = 100;
145 
146                 //Microsoft.Surface.Presentation.Contacts.AddPreviewContactDownHandler(c, CanvasImage_PreviewContactDown);               
147 
148                 c.MouseLeftButtonDown += new MouseButtonEventHandler(Canvas_MouseLeftButtonDown);   //加载鼠标点击事件
149 
150                 #endregion
151 
152                 #region 图片的边框创建与设置
153 
154                 #region 创建一个边框
155                 Rectangle r = new Rectangle(); 
156                 r.Width = 100;
157                 r.Height = 100;
158                 #endregion 
159 
160                 #region 边框填充方法一:直接填充图片所在的边框
161                 // r.Fill = new SolidColorBrush(Colors.Orange);
162                 #endregion
163 
164                 #region 边框填充方法二:手工创建一个Brush,并使用此Brush来填充图片所在的边框
165                 //创建一个Brush
166                 LinearGradientBrush myLGB = new LinearGradientBrush();
167                 myLGB.StartPoint = new Point(0, 0);
168                 myLGB.EndPoint = new Point(0, 1);
169 
170                 GradientStop gs1 = new GradientStop();
171                 gs1.Color = Colors.White;
172                 gs1.Offset = 0.0;
173 
174                 GradientStop gs2 = new GradientStop();
175                 gs2.Color = Colors.Gray;
176                 gs2.Offset = 1.0;
177 
178 
179                 myLGB.GradientStops.Add(gs1);
180                 myLGB.GradientStops.Add(gs2);
181 
182                 //使用上面创建的Brush来填充图片所在的边框
183                 r.Fill = myLGB;
184                 #endregion
185 
186                 r.Stroke = new SolidColorBrush(Colors.Gray);
187 
188                 #endregion
189 
190                 #region 图片控件创建与设置
191 
192                 //创建一个图片控件
193                 Image img = new Image();  
194                 img.Stretch = Stretch.Fill;
195                 img.Width = 80;
196                 img.Height = 80;
197                 img.SetValue(Canvas.LeftProperty, 10.0);
198                 img.SetValue(Canvas.TopProperty, 10.0);
199 
200 
201                 //创建一个图片源对象
202                 Uri uri = new Uri("./images/" + cnt + ".jpg", UriKind.Relative);
203                 ImageSource imgSource = new BitmapImage(uri);
204 
205                 //如果图片小于20张,则重复使用
206                 if (cnt < 20)
207                 {
208                     cnt++;
209                 }
210                 else
211                 {
212                     cnt = 1;
213                 }
214 
215                 img.Source = imgSource;
216 
217                 #endregion
218 
219                 #region 在上面创建的Canvas中添加创建的边框和图片控件
220                 c.Children.Add(r);
221                 c.Children.Add(img);
222                 #endregion
223 
224                 #region 设置图片缩放比例
225                 ScaleTransform st = new ScaleTransform();
226                 st.CenterX = 50;
227                 st.CenterY = 50;
228                 st.ScaleX = 1;
229                 st.ScaleY = 1;
230 
231                 c.RenderTransform = st;
232                 #endregion
233 
234                 #region 图片角度位置的计算与保存
235                 double ang = (double)i * ((Math.PI * 2) / num_images);  //取得对应位置的角度值                
236                 angleValues.Add(ang);  //把角度值保存到List中
237                 #endregion
238                
239                 #region 把上面创建的Canvas添加到页面上
240                 // c.SetValue(Canvas.LeftProperty, i * 100.0);        
241                 root.Children.Add(c);  
242                 #endregion
243             }
244 
245             PositionImagesInCircle();  //放置对应的图片
246         }
247 
248 
249         #endregion
250 
251         #region 设置各个转盘图片在转盘中的位置以及缩放比例+PositionImagesInCircle
252         private void PositionImagesInCircle()
253         {
254             for (int i = 0; i < num_images; i++) //遍历所有指定数量的图片
255             {
256                 //根据角度确定椭圆轨迹上的坐标值
257                 double my_x = (double)Math.Cos((double)angleValues[i]) * radiusX + centerX; //取得X轴坐标值
258                 double my_y = (double)Math.Sin((double)angleValues[i]) * radiusY + centerY; //取得Y轴坐标值
259 
260                 Canvas c = root.FindName("imageHolder_" + i) as Canvas;  //找到子图片所在Canvas
261                 c.SetValue(Canvas.LeftProperty, my_x);  //设置Canvas的坐标值 
262                 c.SetValue(Canvas.TopProperty, my_y);
263                 c.SetValue(Canvas.ZIndexProperty, (int)my_y);  //设置Canvas的显示层次值,在Y坐标上值大图片的覆盖值小的图片 
264 
265                 //缩放变换ScaleTransform允许我们对元素进行缩放,通过属性ScaleX和ScaleY来分别指定在X轴和Y轴上的缩放比例,
266                 //同样也可以使用属性CenterX和CenterY来指定缩放中心
267                 ScaleTransform st = c.RenderTransform as ScaleTransform; 
268 
269 
270                 double my_scale = (my_y - st.ScaleY) / (centerY + radiusY - st.ScaleY);  //按一定方式进行缩放,原则是Y轴值大的图片大,Y轴值小的图片小
271 
272                 //double my_scale = (my_x - st.ScaleX) / (centerX + radiusX - st.ScaleX); //另外一种缩放公式  
273                 //double my_scale = 2 + (double)Math.Cos((double)angleValues[i] - Math.PI / 2);  //另外一种缩放公式  
274 
275 
276                 st.ScaleX = my_scale;
277                 st.ScaleY = my_scale;
278 
279                 angleValues[i] = (double)angleValues[i] + speed;
280 
281             }
282 
283         }
284         #endregion
285 
286         #region myTimer_Tick 事件处理函数
287         void myTimer_Tick(object sender, EventArgs e)
288         {
289             if (main_down)
290             {
291                 PositionImagesInCircle();  //调整图片位置与缩放比例
292             }
293         }
294         #endregion
295 
296         #endregion
297 
298         private void numPhotosSliderChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
299         {
300             Slider s = sender as Slider;
301 
302             if (page_loaded) //如果页面已经加载
303             {
304                 RemoveImages();  //移除所有图片
305 
306                 num_images = (int)s.Value; //重新设置当前应该加载的图片数量
307 
308                 BuildImages();  //重新加载图片
309             }
310         }
311 
312         private void ResetImagesButton_Click(object sender, RoutedEventArgs e)
313         {
314             RemoveImages();  //清除所有图片
315 
316             #region 恢复变量默认初始值#region 恢复变量默认初始值
317             num_images = 20; 
318             radiusX = 500;
319             radiusY = 110;
320             centerX = 460;
321             centerY = 260;
322             mainImage.SetValue(Canvas.ZIndexProperty, 169);
323             #endregion
324 
325             BuildImages();  //重新加载指定数量的图片
326 
327             #region 重新设置滑条默认值#region 重新设置滑条默认值
328             numPhotosSlider.Value = 40.0;
329             radiusSliderX.Value = 500;
330             radiusSliderY.Value = 1100;
331             #endregion
332         }
333 
334         private void radiusSliderChangedX(object sender, RoutedPropertyChangedEventArgs<double> e)
335         {
336             Slider s = sender as Slider;
337 
338             if (page_loaded) //如果页面已经成功加载则作后续处理
339             {
340                 RemoveImages();  //移除所有图片
341 
342                 radiusX = (int)s.Value; //取得新的半径值
343 
344                 if (s.Value < 450)  //如果新的半径值低于我们要求的上限,则作调整,否则不作变动
345                 {
346                     //调整mainImage控件的ZIndexProperty属性,以免它因为radius的变动被后面的图片轮挡住
347                     int z = (int)mainImage.GetValue(Canvas.ZIndexProperty);
348                     z += 2;
349                     mainImage.SetValue(Canvas.ZIndexProperty, z);
350                 }
351                 else
352                 {
353                     mainImage.SetValue(Canvas.ZIndexProperty, 169);
354                 }
355 
356                 BuildImages(); //重新加载图片 
357             }
358 
359         }
360 
361 
362         private void MainContactDown(object sender, MouseButtonEventArgs e)
363         {
364             Point p = e.GetPosition(this);
365             Debug.WriteLine(">>" + p.Y);
366             if (p.Y > 500 && p.Y < 650)  //判断是否在指定的区域内按下了鼠标
367             {
368                 main_down = true;
369             }
370         }
371 
372         private void MainContactUp(object sender, MouseButtonEventArgs e)
373         {
374             main_down = false;
375         }
376 
377         private void root_MouseMove(object sender, MouseEventArgs e)
378         {
379             Point p = e.GetPosition(this);
380             speed = ((p.X - 500) / 500) * 0.0755;  //调整轮盘的转速
381             //Debug.WriteLine("changed: " + speed);
382         }
383 
384         private void radiusSliderChangedY(object sender, RoutedPropertyChangedEventArgs<double> e)
385         {
386             Slider s = sender as Slider;
387             if (page_loaded) //如果页面已经成功加载则作后续处理
388             {
389                 RemoveImages();  //移除所有图片
390 
391                 radiusY = (int)s.Value; //取得新的半径值
392                 if (s.Value < 200)  //如果新的半径值低于我们要求的上限,则作调整,否则不作变动
393                 {
394                     //调整mainImage控件的ZIndexProperty属性,以免它因为radius的变动被后面的图片轮挡住
395                     int z = (int)mainImage.GetValue(Canvas.ZIndexProperty);
396                     z += 2;
397                     mainImage.SetValue(Canvas.ZIndexProperty, z);
398                 }
399                 else
400                 {
401                     mainImage.SetValue(Canvas.ZIndexProperty, 169);
402                 }
403 
404                 BuildImages(); //重新加载图片 
405             }
406         }
407 
408         #region autoTimer_Tick 事件处理函数#region autoTimer_Tick 事件处理函数
409         void autoTimer_Tick(object sender, EventArgs e)
410         {
411                 PositionImagesInCircle();  //调整图片位置与缩放比例
412         }
413         #endregion
414 
415         private void AutoSpinButton_Click(object sender, RoutedEventArgs e)
416         {
417             autoTimer.Start();
418             autoTimer.Interval = TimeSpan.FromMilliseconds(33);
419             autoTimer.Tick += new EventHandler(autoTimer_Tick);
420         }
421     }
422 }
View Code

 

posted @ 2014-04-09 09:31  IT新秀(星火燎原)  阅读(240)  评论(0编辑  收藏  举报