原文:
用WPF輕鬆打造iTunes CoverFlow效果
用WPF輕鬆打造iTunes CoverFlow效果
周銀輝html
源代碼下載點這裏
先Show一下:
下面這一張是蘋果的iTunes軟件:
蘋果iTunes播放器的CoverFlow效果羨煞旁人,不過有了WPF,咱們也能夠輕鬆實現哈,今天費了半天的時間終於搞定,呵呵...佈局
感興趣的話能夠這裏下載源代碼
(說明:上傳源代碼時因爲圖片較大,因此就沒傳圖片了,程序取的是用戶" 個人圖片"文件夾下的*.jpg圖片,你能夠修改代碼中的路徑或在"個人圖片"文件夾下放幾張jpg圖片就能夠看到效果了)
圖片是使用3DTools 提供的2D到3D映射的方式貼圖上去的,每張圖片都帖在一個3D模型上,咱們只須要讓程序來安排這些模型的擺放位置就能夠了
3D模型的擺放是按照以下方法進行的,其中3個傳出參數angle指定模型源Y軸的旋轉角度,offsetX指定模型的X軸方向上的平移量,offsetZ指定模型在Z軸方向上的平移量動畫
/**/
/// <summary>
/// 依照InteractiveVisual3D在列表中的序號來變換其位置等
/// </summary>
/// <param name="index">在列表中的序號</param>
/// <param name="midIndex">列表中被做爲中間項的序號</param>
private
void
GetTransformOfInteractiveVisual3D(
int
index,
double
midIndex,
out
double
angle,
out
double
offsetX,
out
double
offsetZ)
{
double disToMidIndex = index - midIndex;
//旋轉,兩翼的圖片各旋轉必定的度數
angle = 0;
if (disToMidIndex < 0)
{
angle = this.ModelAngle;//左邊的旋轉N度
}
else if (disToMidIndex > 0)
{
angle = (-this.ModelAngle);//右邊的旋轉-N度
}
//平移,兩翼的圖片逐漸向X軸負和正兩個方向展開
offsetX = 0;//中間的不平移
if (Math.Abs(disToMidIndex) <= 1)
{
offsetX = disToMidIndex * this.MidModelDistance;
}
else if (disToMidIndex != 0)
{
offsetX = disToMidIndex * this.XDistanceBetweenModels + (disToMidIndex > 0 ? this.MidModelDistance : -this.MidModelDistance);
}
//兩翼的圖片逐漸向Z軸負方向移動一點,形成中間突出(離觀衆較近的效果)
offsetZ = Math.Abs(disToMidIndex) * -this.ZDistanceBetweenModels;
}
點擊圖片或指定當前應該被突出顯示的圖片時的動畫效果是這樣實現的,先使用上面的方法計算出決定模型位置的幾個便量的新值(即上面的幾個傳出參數),而後在使用動畫(DoubleAnimation)讓這幾個值由舊值過分到新值.ui
/**/
/// <summary>
/// 從新佈局3D內容
/// </summary>
private
void
ReLayoutInteractiveVisual3D()
{
int j=0;
for (int i = 0; i < this.viewport3D.Children.Count; i++)
{
InteractiveVisual3D iv3d = this.viewport3D.Children[i] as InteractiveVisual3D;
if(iv3d != null)
{
double angle = 0;
double offsetX = 0;
double offsetZ = 0;
this.GetTransformOfInteractiveVisual3D(j++, this.CurrentMidIndex,out angle,out offsetX,out offsetZ);
NameScope.SetNameScope(this, new NameScope());
this.RegisterName("iv3d", iv3d);
Duration time = new Duration(TimeSpan.FromSeconds(0.3));
DoubleAnimation angleAnimation = new DoubleAnimation(angle, time);
DoubleAnimation xAnimation = new DoubleAnimation(offsetX, time);
DoubleAnimation zAnimation = new DoubleAnimation(offsetZ, time);
Storyboard story = new Storyboard();
story.Children.Add(angleAnimation);
story.Children.Add(xAnimation);
story.Children.Add(zAnimation);
Storyboard.SetTargetName(angleAnimation, "iv3d");
Storyboard.SetTargetName(xAnimation, "iv3d");
Storyboard.SetTargetName(zAnimation, "iv3d");
Storyboard.SetTargetProperty(
angleAnimation,
new PropertyPath("(ModelVisual3D.Transform).(Transform3DGroup.Children)[0].(RotateTransform3D.Rotation).(AxisAngleRotation3D.Angle)"));
Storyboard.SetTargetProperty(
xAnimation,
new PropertyPath("(ModelVisual3D.Transform).(Transform3DGroup.Children)[1].(TranslateTransform3D.OffsetX)"));
Storyboard.SetTargetProperty(
zAnimation,
new PropertyPath("(ModelVisual3D.Transform).(Transform3DGroup.Children)[1].(TranslateTransform3D.OffsetZ)"));
story.Begin(this);
}
}
}