wpf的3D是一個很有意思的東西,類似於ps的效果,類似於電影動畫的效果,因為動畫的效果,(對於3D基礎的攝像機,光源,之類不介紹,對於依賴屬性也不介紹。),個人認為,依賴屬性這個東西,有百分之五十是為了3D而存在。
(自己寫的類似於demo的東西)
先上圖,無圖無真相
這是demo的整個效果圖,可以用鼠標移動,觸摸屏也可以手指滑動,圖片會移動,然后移動結束,會有一個回彈的判斷。
<Window x:Class="_3Dshow.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Demo" Height="441" Width="702" Background="LightGray" xmlns:System="clr-namespace:System;assembly=mscorlib"> <Grid PreviewMouseDown="_view_mousedown" PreviewMouseMove="_view_mousemove" PreviewMouseUp="_view_mouseup" > <Border Background="LightGray" Padding="2" Margin="0,-41,0,-40"> <Viewport3D x:Name="_view" > </Viewport3D> </Border> </Grid> </Window>
xmal,很簡單 一個viewport3D,還有就是鼠標事件,這里如果你深入研究,會發現比較有意思的事情,路由事件!
從grid 路由到viewground,如果外面再嵌套一個canvas,會更清晰。
個人認為路由事件比較扯淡的是,我想讓grid處理不讓viewport3d處理,或者又想讓grid處理又想讓viewport3d處理,這是很有意思的事情。
好,這里不多啰嗦,上代碼
#region 全局函數 // Queue<double>[,] sum_queue; double[,] sum_queue = new double[5, 2]; PerspectiveCamera _camera = null; bool ismousedown = false; // TimeSpan timspan; Point startPoint, currentPoint, endPoint; string[] fileList; double[,] sum_list; int _b = 0; DispatcherTimer sub_time = new DispatcherTimer(); DispatcherTimer sub_time1 = new DispatcherTimer(); private static DependencyProperty TranslatePosProperty = DependencyProperty.Register( "TranslatePos", typeof(double), typeof(Window1), new PropertyMetadata((double)0, new PropertyChangedCallback(DragPosChanged))); #endregion
一個依賴屬性,兩個dispatchertimer,一個用於控制拖拽動畫,一個用於托抓完畢后的回彈效果,通過animation來改變依賴屬性,進一步達到控制整個頁面的效果。
依賴屬性的回測事件(我自己把這種回傳事件稱之為回測事件,個人喜好)
#region temp double _pos = 0; void PosChanged(double pos) { double delta = pos - _pos; _pos = pos; GetTran(delta); } #endregion
下面是核心代碼,我用一個數組存放了所有的圖片,圖片的位置,圖片的偏轉角度,圖片的縮放大小,圖片在左邊還是在右邊的一個標識位,最后通過設置Transform 來改變圖片,其實不能說是圖片了,因為他是一個個元素,viewport的元素,這些元素自身有Transform 這個屬性,所以直接用這個設置,我還沒有找到用動畫或者故事板控制的方法。
private void GetTran(double sum) { for (int i = 0; i < _view.Children.Count; i++) { #region point move #region 調整位置 sum_list[i, 1] += sum / 270; //angel if (sum > 0) { if (sum_list[i, 4] == -2) { sum_list[i, 3] += sum / 2000; } else if (sum_list[i, 4] == 0) { sum_list[i, 3] -= sum / 2000; } else if (sum_list[i, 4] == 2) { sum_list[i, 3] -= sum / 2000; } } else { if (sum_list[i, 4] == -2) { sum_list[i, 3] += sum / 2000; } else if (sum_list[i, 4] == 0) { sum_list[i, 3] += sum / 2000; } else if (sum_list[i, 4] == 2) { sum_list[i, 3] -= sum / 2000; } } if (sum > 0) { if (sum_list[i, 2] == 0) { sum_list[i, 4] = 2; } sum_list[i, 2] -= sum / 10; if (sum_list[i, 2] == 0) { sum_list[i, 4] = 0; } } else if (sum < 0) { if (sum_list[i, 2] == 0) { sum_list[i, 4] = -2; } sum_list[i, 2] -= sum / 10; if (sum_list[i, 2] == 0) { sum_list[i, 4] = 0; } } #endregion Transform3DGroup tg = new Transform3DGroup(); tg.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), sum_list[i, 2]))); tg.Children.Add(new ScaleTransform3D(sum_list[i, 3], sum_list[i, 3], sum_list[i, 3])); tg.Children.Add(new TranslateTransform3D(sum_list[i, 1], 0, sum_list[i, 0])); _view.Children[i].Transform = tg; #endregion } Volidating(); }
最后會有一個校驗,校驗是讓設置每個圖片是否超標,以及設置他們到和初始相比較的狀態
private void Volidating() { for (int i = 0; i < _view.Children.Count; i++) { if (sum_list[i, 3] >= 1) { sum_list[i, 1] = 0; sum_list[i, 3] = 1; sum_list[i, 2] = 0; sum_list[i, 4] = 0; int sum = 1; for (int j = i - 1; j >= 0; j--) { sum_list[j, 3] = 1 - (0.2) * sum; if (sum_list[j, 3] <= 0) { sum_list[j, 3] = 0; } sum_list[j, 2] = 40 * sum; sum_list[j, 1] = -1.5 * sum; sum++; } sum = 1; for (int j = i + 1; j < _view.Children.Count; j++) { sum_list[j, 3] = 1 - (0.2) * sum; if (sum_list[j, 3] <= 0) { sum_list[j, 3] = 0; } sum_list[j, 2] = 40 * sum * (-1); sum_list[j, 1] = 1.5 * sum; sum++; } break; } } }
當鼠標點擊時候,我記錄下一個坐標,鼠標移動時,我記錄下一個坐標,鼠標起來時,我記錄一個坐標,鼠標移動時,觸發第一個timer,鼠標起來時,觸發第二個timer。
這些就是基本思路,寫的很隨性,思維不縝密,10年11月時候花了一周時間寫的,我並不是說我怎么怎么樣,nb或者sb,只是有些懷念。
那時候研究wpf,一心要涉足這個方向,對於動畫一知半解,wpf相對於winform是一個全新的東西,現在看這些代碼,或許覺得搖頭或者覺得垃圾,但是很懷念那時候還年輕的時候,用最笨的方法實現想要的東西,為此而加班至深夜。
有時候為了找一些問題,google出來,千篇一律,copy是常見,稍微帶源碼的都要注冊,積分,很不喜歡把程序商品化,共享討論才能有改進,所以就把之前的代碼發來討論一下,如有興趣,可以繼續改進。
(我們是拉風的程序員,不是屌絲)
謹祝福'那時候終日不知疲倦,反復坐在電腦旁測試,看着自己寫出的東西,在心里自己對自己說:看,這是我寫出來的東西。'又奔波不已的所有程序員。
源碼:
files.cnblogs.com/fish124423/3Dshow.rar