c#翻页效果
用c#和GDI+實現(xiàn)雜志翻頁動畫效果時間:2010-01-13 blog.csdn.net 周公 -
說明:以前本人參與個一個電子雜志項目,當(dāng)時要求實現(xiàn)模擬現(xiàn)實生活中的雜志翻頁動畫效果,別人推薦了這篇文章,最后達(dá)到了我想要的效果,今天嘗試把這篇文章翻譯了一下。希望對英語水平不太好的同行有幫助。如果你的英語水平足夠好,我推薦你閱讀英文原文,網(wǎng)址是:http://www.codeproject.com/KB/GDI-plus/TurnThePage.aspx,同時希望大家原諒本人的翻譯水平。
介紹圖1 翻頁效果這篇文章用來介紹如何在電子書或者電子相冊中并列顯示圖片時創(chuàng)建一種翻頁效果,這種翻頁效果模仿了現(xiàn)實中的書本翻頁情況。背景寫作這篇文章的靈感來自于一個可重用的用于顯示圖片的組件的需求。我使用了C#和GDI+來提高我對.net下圖形圖象編程的理解。
創(chuàng)建這種效果的技術(shù)背景來自于一篇文章《FalshMX中的翻頁效果》,網(wǎng)址是:http://www.oreillynet.com/pub/a/javascript/2004/09/03/flashhacks.html,作者是Sham Bhangal。Sham在文章里如何在動畫效果中使用對稱線來控制頁面的可見部分。盡管在Flash MX中和在GDI+中的處理有些不同,但是利用對稱線來計算頁面的可見部分這個概念是相同的。
在這篇文章中,我們假定第3頁和第4頁是當(dāng)前頁,并且下一個動作是要翻到第5頁和第6頁。換句話說,我們要展現(xiàn)的是第4頁的翻頁效果。動畫技巧下圖闡述了在整個動畫中的關(guān)鍵區(qū)域和變化區(qū)域。圖2 關(guān)鍵區(qū)域和參數(shù)本文來自編程入門網(wǎng):http://www.bianceng.cn/Programming/csharp/201001/14287.htm
整個翻頁動畫可以概括為:1、完全繪制出第3頁和第4頁。在繪制完成之后,B和C部分將會遮擋住第4頁的原來可見部分。2、計算出對稱線和B和C的裁剪區(qū)域。3、繪制B部分。這是下面的一頁的部分區(qū)域(第6頁)。4、根據(jù)熱點進(jìn)行相應(yīng)轉(zhuǎn)換,并且進(jìn)行相應(yīng)旋轉(zhuǎn)。5、繪制C部分。這是第4頁在翻頁過程中顯示的它的背面(第5頁)的內(nèi)容。當(dāng)前頁《FalshMX中的翻頁效果》一文中指出當(dāng)前頁并不參與翻頁效果。這就意味著在翻頁中的每一面(第3頁和第4頁)都會首先被不進(jìn)行任何裁減和轉(zhuǎn)換就繪制出來。B和C這兩個可見部分將會在當(dāng)前頁之上進(jìn)行繪制。熱點“熱點”這個詞是我從《FalshMX中的翻頁效果》一文中借鑒過來的。熱點一詞代表在翻頁時折痕在水平軸線上的位置,它標(biāo)明對稱線的起始位置。在翻頁過程中,熱點一直在從頁邊緣到書中間這段距離之間移動。從頁邊到熱點的這段距離(x)將隨著頁面的翻動而變化。當(dāng)熱點到達(dá)書的中間位置時,動畫就停止了,這時x=PAGE_WIDTH。對稱線對稱線代表翻頁時頁面的折痕。它是用于計算在翻頁時參與的頁面可見部分。在程序中,對稱線控制兩件事情:1、B和C部分的裁剪區(qū)域。本文來自編程入門網(wǎng):http://www.bianceng.cn/Programming/csharp/201001/14287_2.htm
2、C部分進(jìn)行轉(zhuǎn)換的坐標(biāo)原點。對稱線可以用下面兩個等式來描述:a = 45 + ( (45 *x) / PAGE_WIDTH )h = x Tan ( a )注意角度a會隨著x的變化而變化。這個等式表明當(dāng)x=0時a = 45度并且當(dāng)x= PAGE_WIDTH時a = 90度。當(dāng)動畫開始時,x=0,因此B和C部分并不可見。隨著x的增加,對稱線就形成了直角三角形的斜邊。三角形由三個長度確定:對稱線、x和高度h。圖2展示了這樣一種情況。隨著x的增加,將會出現(xiàn)h>= PAGE_WIDTH的情況。當(dāng)這種情況出現(xiàn)后,對稱線與頁面相交的區(qū)域?qū)扇切巫兂商菪巍L菪蔚母叨染褪荘AGE_WIDTH。圖1就是這種情況。不管是梯形還是三角形,這個閉合路線都指出了B和C這兩個裁減區(qū)域。要想看到運行中看到這種帶有邊框的效果,在提供的源代碼中將INCLUDE_DRAW_GRAPHICS_PATH這個參數(shù)設(shè)置為true就行了。程序?qū)陂]合路徑的外面繪制出一個金色的輪廓。A部分區(qū)域這部分是要翻動的頁面在裁減出B和C部分之后的可見部分(第4頁)。B部分區(qū)域B部分來自于正在翻動的頁面的之下的另一頁面,在這個例子中指的是第6頁的可見部分。B部分區(qū)域就是被對稱線與頁面形成的閉合曲線所裁減的部分。在這個部分之上的頁面(第4頁)的相應(yīng)部分將會被直接裁減掉。顯而易見,隨著x的增加(a也隨著增加),這個可見部分將會越來越大。要想看A和B部分區(qū)域的關(guān)系,請將INCLUDE_UNDERSIDE_PAGE_IN_ANIMATION變量設(shè)置為false。這將把C部分從動畫效果中去掉。C部分區(qū)域C部分區(qū)域的圖象表示了正在翻動的頁面的背面的圖象。在這個例子中,C部分區(qū)域代表了第5頁的可見部分。C部分也是通過對稱線指定的,但是是在頁面的這一邊(對稱線的左邊)。舉個例子,當(dāng)翻動第4頁時,B部分將會是第6頁的右下部分,而C部分將會是第5頁的左下部分。圖3展示了B和C之間的關(guān)系。圖3 B和C之間的關(guān)系本文來自編程入門網(wǎng):http://www.bianceng.cn/Programming/csharp/201001/14287_3.htm
在繪制C部分區(qū)域時,我們用了一個后臺的圖象來輔助,就是pageUndersideImage。這個新圖象的裁減區(qū)域通過對稱線來確定。第5頁的圖象被繪制在這個新的緩沖區(qū)里面,這個新建的圖象將會靠近B部分區(qū)域繪制。連接B和C部分區(qū)域當(dāng)C部分的后臺圖像已經(jīng)準(zhǔn)備好,它通過下面的步驟繪制:首先調(diào)整系統(tǒng)坐標(biāo)到熱點。將系統(tǒng)坐標(biāo)旋轉(zhuǎn)180-2a度,請看圖4了解它們的關(guān)系。將含有C部分區(qū)域的圖像繪制到相應(yīng)坐標(biāo)(-x,-PAGE_HEIGHT)。圖5標(biāo)明了這種旋轉(zhuǎn)。圖4 調(diào)整角度以匹配對稱線圖5 旋轉(zhuǎn)坐標(biāo)系我發(fā)現(xiàn)沿著對稱線排列B和C部分區(qū)域非常具有挑戰(zhàn)性因為當(dāng)前頁面的顏色容易出“血邊”(因為第4頁的一些紅色像素)。當(dāng)我繪制B或者C部分區(qū)域時,我用了一個變通方法:指定圖形對象的pixeloffsetmode以pixeloffsetmode.half方式繪制。g.PixelOffsetMode= PixelOffsetMode.Half;我還發(fā)現(xiàn),在繪制C部分區(qū)域之前,增加一個像素(或者減掉一個像素)來旋轉(zhuǎn)坐標(biāo)也可以防止出“血邊”。PathTranslationMatrix.Translate((float)hotSpot.Origin.X+1,(float)hotSpot.Origin.Y);要使用pixeloffsetmode變通方法,請將源代碼中的USE_PIXEL_MODE_OFFSET設(shè)置為true。-本文來自編程入門網(wǎng):http://www.bianceng.cn/Programming/csharp/201001/14287_4.htm
繪制動畫每一幀動畫都是在timer1_Tick方法中繪制到緩沖區(qū)中的CurrentShownBitmap對象上。CurrentShownBitmap方法僅僅是將繪制到屏幕上。主要功能說明計算動畫中每一幀里B和C部分的圖象都是由以下方法完成的:private GraphicsPath GetPageUnderGraphicsPath(int x,refdouble a, int height, int width,bool isUnderSide, TurnType type)參數(shù)x代表從頁面邊緣到熱點處的距離(前面已經(jīng)說明),height和width參數(shù)代表當(dāng)前頁面要顯示的高度和寬度。isUnderSide參數(shù)用來告訴程序是否在計算C部分區(qū)域(正在翻動的那一頁的背面),最后一個參數(shù)type是表示頁面是左翻頁還是右翻頁。基本上,isUnderSide和type參數(shù)是用來獲取圖形路徑的正確性的,參數(shù)a如上所述是代表當(dāng)前角度的。參數(shù)a傳遞的是引用,隨后將在繪制C之前用于旋轉(zhuǎn)坐標(biāo)(見圖4和圖5)。使用代碼安裝控件為了簡單起見,這個控件有自己的圖片。初始化圖象的代碼在LoadSamples()方法中。這個方法在Sample類的構(gòu)造方法中調(diào)用。控制翻頁的速度和數(shù)目翻頁的速度是通過一個timer來控制的,public屬性TickSpeed能用來控制翻頁速度(毫秒為單位),動畫的幀數(shù)是通過每個timer間隔熱點移動的距離來控制的。public屬性暴露給外界以控制已經(jīng)移動的距離x。調(diào)整高度沿著背頁的頂部裁減是一個問題,public屬性HeightAdjustment用于在控件頂部留一點空白區(qū)域便于裁剪。開始動畫這個組件公開兩個方法來開始動畫。animateRightPageTurn() and animateLeftPageTurn().注意事項我本來試圖解當(dāng)h=PAGE_HEIGHT時的非線性方程h = x Tan( 45 + ((45 * (x)) / PAGE_WIDTH) )中的x的值,我的這個蠻力辦法的代碼包含在源代碼中。是不是還有一個更優(yōu)雅的辦法呢?說明:程序的源代碼可以到http://download.csdn.net/source/381727下載。
本文來自編程入門網(wǎng):http://www.bianceng.cn/Programming/csharp/201001/14287_5.htm View Code
用c#和GDI+實現(xiàn)雜志翻頁動畫效果詳解
說明:以前本人參與個一個電子雜志項目,當(dāng)時要求實現(xiàn)模擬現(xiàn)實生活中的雜志翻頁動畫效果,別人推薦了這篇文章,最后達(dá)到了我想要的效果,今天嘗試把這篇文章翻譯了一下。希望對英語水平不太好的同行有幫助。如果你的英語水平足夠好,我推薦你閱讀英文原文,網(wǎng)址是:http://www.codeproject.com/KB/GDI-plus/TurnThePage.ASPx,同時希望大家原諒本人的翻譯水平。 介紹圖1 翻頁效果這篇文章用來介紹如何在電子書或者電子相冊中并列顯示圖片時創(chuàng)建一種翻頁效果,這種翻頁效果模仿了現(xiàn)實中的書本翻頁情況。背景寫作這篇文章的靈感來自于一個可重用的用于顯示圖片的組件的需求。我使用了C#和GDI+來提高我對.net下圖形圖象編程的理解。創(chuàng)建這種效果的技術(shù)背景來自于一篇文章《FalshMX中的翻頁效果》,網(wǎng)址是:http://www.oreillynet.com/pub/a/JavaScript/2004/09/03/flashhacks.html,作者是Sham Bhangal。Sham在文章里如何在動畫效果中使用對稱線來控制頁面的可見部分。盡管在Flash MX中和在GDI+中的處理有些不同,但是利用對稱線來計算頁面的可見部分這個概念是相同的。 在這篇文章中,我們假定第3頁和第4頁是當(dāng)前頁,并且下一個動作是要翻到第5頁和第6頁。換句話說,我們要展現(xiàn)的是第4頁的翻頁效果。動畫技巧下圖闡述了在整個動畫中的關(guān)鍵區(qū)域和變化區(qū)域。圖2 關(guān)鍵區(qū)域和參數(shù)整個翻頁動畫可以概括為:1、完全繪制出第3頁和第4頁。在繪制完成之后,B和C部分將會遮擋住第4頁的原來可見部分。2、計算出對稱線和B和C的裁剪區(qū)域。3、繪制B部分。這是下面的一頁的部分區(qū)域(第6頁)。4、根據(jù)熱點進(jìn)行相應(yīng)轉(zhuǎn)換,并且進(jìn)行相應(yīng)旋轉(zhuǎn)。5、繪制C部分。這是第4頁在翻頁過程中顯示的它的背面(第5頁)的內(nèi)容。當(dāng)前頁《FalshMX中的翻頁效果》一文中指出當(dāng)前頁并不參與翻頁效果。這就意味著在翻頁中的每一面(第3頁和第4頁)都會首先被不進(jìn)行任何裁減和轉(zhuǎn)換就繪制出來。B和C這兩個可見部分將會在當(dāng)前頁之上進(jìn)行繪制。熱點“熱點”這個詞是我從《FalshMX中的翻頁效果》一文中借鑒過來的。熱點一詞代表在翻頁時折痕在水平軸線上的位置,它標(biāo)明對稱線的起始位置。在翻頁過程中,熱點一直在從頁邊緣到書中間這段距離之間移動。從頁邊到熱點的這段距離(x)將隨著頁面的翻動而變化。當(dāng)熱點到達(dá)書的中間位置時,動畫就停止了,這時x=PAGE_WIDTH。對稱線對稱線代表翻頁時頁面的折痕。它是用于計算在翻頁時參與的頁面可見部分。在程序中,對稱線控制兩件事情:1、B和C部分的裁剪區(qū)域。2、C部分進(jìn)行轉(zhuǎn)換的坐標(biāo)原點。對稱線可以用下面兩個等式來描述:a = 45 + ( (45 *x) / PAGE_WIDTH )h = x Tan ( a )注意角度a會隨著x的變化而變化。這個等式表明當(dāng)x=0時a = 45度并且當(dāng)x= PAGE_WIDTH時a = 90度。當(dāng)動畫開始時,x=0,因此B和C部分并不可見。隨著x的增加,對稱線就形成了直角三角形的斜邊。三角形由三個長度確定:對稱線、x和高度h。圖2展示了這樣一種情況。 隨著x的增加,將會出現(xiàn)h>= PAGE_WIDTH的情況。當(dāng)這種情況出現(xiàn)后,對稱線與頁面相交的區(qū)域?qū)扇切巫兂商菪巍L菪蔚母叨染褪荘AGE_WIDTH。圖1就是這種情況。不管是梯形還是三角形,這個閉合路線都指出了B和C這兩個裁減區(qū)域。要想看到運行中看到這種帶有邊框的效果,在提供的源代碼中將INCLUDE_DRAW_GRAPHICS_PATH這個參數(shù)設(shè)置為true就行了。程序?qū)陂]合路徑的外面繪制出一個金色的輪廓。A部分區(qū)域這部分是要翻動的頁面在裁減出B和C部分之后的可見部分(第4頁)。B部分區(qū)域B部分來自于正在翻動的頁面的之下的另一頁面,在這個例子中指的是第6頁的可見部分。B部分區(qū)域就是被對稱線與頁面形成的閉合曲線所裁減的部分。在這個部分之上的頁面(第4頁)的相應(yīng)部分將會被直接裁減掉。顯而易見,隨著x的增加(a也隨著增加),這個可見部分將會越來越大。要想看A和B部分區(qū)域的關(guān)系,請將INCLUDE_UNDERSIDE_PAGE_IN_ANIMATION變量設(shè)置為false。這將把C部分從動畫效果中去掉。C部分區(qū)域C部分區(qū)域的圖象表示了正在翻動的頁面的背面的圖象。在這個例子中,C部分區(qū)域代表了第5頁的可見部分。C部分也是通過對稱線指定的,但是是在頁面的這一邊(對稱線的左邊)。舉個例子,當(dāng)翻動第4頁時,B部分將會是第6頁的右下部分,而C部分將會是第5頁的左下部分。圖3展示了B和C之間的關(guān)系。圖3 B和C之間的關(guān)系在繪制C部分區(qū)域時,我們用了一個后臺的圖象來輔助,就是pageUndersideImage。這個新圖象的裁減區(qū)域通過對稱線來確定。第5頁的圖象被繪制在這個新的緩沖區(qū)里面,這個新建的圖象將會靠近B部分區(qū)域繪制。 連接B和C部分區(qū)域當(dāng)C部分的后臺圖像已經(jīng)準(zhǔn)備好,它通過下面的步驟繪制:首先調(diào)整系統(tǒng)坐標(biāo)到熱點。將系統(tǒng)坐標(biāo)旋轉(zhuǎn)180-2a度,請看圖4了解它們的關(guān)系。將含有C部分區(qū)域的圖像繪制到相應(yīng)坐標(biāo)(-x,-PAGE_HEIGHT)。圖5標(biāo)明了這種旋轉(zhuǎn)。圖4 調(diào)整角度以匹配對稱線圖5 旋轉(zhuǎn)坐標(biāo)系我發(fā)現(xiàn)沿著對稱線排列B和C部分區(qū)域非常具有挑戰(zhàn)性因為當(dāng)前頁面的顏色容易出“血邊”(因為第4頁的一些紅色像素)。當(dāng)我繪制B或者C部分區(qū)域時,我用了一個變通方法:指定圖形對象的pixeloffsetmode以pixeloffsetmode.half方式繪制。g.PixelOffsetMode= PixelOffsetMode.Half;我還發(fā)現(xiàn),在繪制C部分區(qū)域之前,增加一個像素(或者減掉一個像素)來旋轉(zhuǎn)坐標(biāo)也可以防止出“血邊”。PathTranslationMatrix.Translate((float)hotSpot.Origin.X+1,(float)hotSpot.Origin.Y);要使用pixeloffsetmode變通方法,請將源代碼中的USE_PIXEL_MODE_OFFSET設(shè)置為true。繪制動畫每一幀動畫都是在timer1_Tick方法中繪制到緩沖區(qū)中的CurrentShownBitmap對象上。CurrentShownBitmap方法僅僅是將繪制到屏幕上。主要功能說明計算動畫中每一幀里B和C部分的圖象都是由以下方法完成的:private GraphicsPath GetPageUnderGraphicsPath(int x,refdouble a, int height, int width,bool isUnderSide, TurnType type)參數(shù)x代表從頁面邊緣到熱點處的距離(前面已經(jīng)說明),height和width參數(shù)代表當(dāng)前頁面要顯示的高度和寬度。isUnderSide參數(shù)用來告訴程序是否在計算C部分區(qū)域(正在翻動的那一頁的背面),最后一個參數(shù)type是表示頁面是左翻頁還是右翻頁。基本上,isUnderSide和type參數(shù)是用來獲取圖形路徑的正確性的,參數(shù)a如上所述是代表當(dāng)前角度的。參數(shù)a傳遞的是引用,隨后將在繪制C之前用于旋轉(zhuǎn)坐標(biāo)(見圖4和圖5)。使用代碼安裝控件為了簡單起見,這個控件有自己的圖片。初始化圖象的代碼在LoadSamples()方法中。這個方法在Sample類的構(gòu)造方法中調(diào)用。控制翻頁的速度和數(shù)目翻頁的速度是通過一個timer來控制的,public屬性TickSpeed能用來控制翻頁速度(毫秒為單位),動畫的幀數(shù)是通過每個timer間隔熱點移動的距離來控制的。public屬性暴露給外界以控制已經(jīng)移動的距離x。調(diào)整高度沿著背頁的頂部裁減是一個問題,public屬性HeightAdjustment用于在控件頂部留一點空白區(qū)域便于裁剪。開始動畫這個組件公開兩個方法來開始動畫。animateRightPageTurn() and animateLeftPageTurn().注意事項我本來試圖解當(dāng)h=PAGE_HEIGHT時的非線性方程h = x Tan( 45 + ((45 * (x)) / PAGE_WIDTH) )中的x的值,我的這個蠻力辦法的代碼包含在源代碼中。是不是還有一個更優(yōu)雅的辦法呢?說明:程序的源代碼可以到http://download.csdn.net/source/381727下載。 View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/blogpro/p/11465115.html
總結(jié)
- 上一篇: python中计算a的b次方
- 下一篇: 1 用Matlab 程序对AM调制,基于