我最近在使用F#的Silverlight中實現了動畫打字機效果。我的代碼有效,但我想看看是否有人對代碼的改進方式提出建議。即用Seq.iter或Seq.map來做它是好的還是壞主意?歡迎任何意見和評論!F#:Silverlight中的打字機效果
我還以爲我會記錄代碼的情況下,它可能會幫助別人
反饋編輯:增加了對掛鉤動畫,在跳出的故事板
let createTypewriter(text:string) =
//Controls the animation of each character
let storyboard = new Storyboard()
//This will contain every line of text
let textboard = new StackPanel(Orientation=Orientation.Vertical)
//Creates a new StackPanel to hold the words and puts it in the wrapPanel
let newWordContainer (wrapPanel:WrapPanel) =
let wordContainer = new StackPanel(Orientation=Orientation.Horizontal)
wrapPanel.Children.Add(wordContainer)
wordContainer
//Parse the entire string
let rec parseLetters letter delay wordContainer wrapPanel : Storyboard * StackPanel =
match letter with
//If there's nothing left to parse return the initialized storyboard
//and textboard
| [] -> (storyboard, textboard)
//Using pattern matching we recursively handle the current character (head)
//then rest of the characters (tail)
//Handle Spaces. If we encounter a space, we create a new horizontal
//StackPanel to put individual characters into. This new StackPanel
//is added to the wrapPanel
| head :: tail when head = ' ' ->
let newCont = newWordContainer wrapPanel
newCont.Children.Add(new TextBlock(Text=" "))
parseLetters tail (delay+1.0) newCont wrapPanel
//If we encounter a newline or a return, we want to move down to a new line.
//Thus we insert a new WrapPanel into our vertical StackPanel (textboard)
| head :: tail when head ='\n' || head = '\r' -> //Handle new lines
let newWrapPanel = new WrapPanel(MinHeight = this.FontSize)
let newCont = newWordContainer newWrapPanel
textboard.Children.Add(newWrapPanel)
parseLetters tail (delay+1.0) newCont newWrapPanel
//Letters will be placed in TextBlocks and added to horizontal StackPanels
//(wordContainer) to make words. Each TextBlock will have an animation
//controlled by the StoryBoard.
| head :: tail ->
//Create the animation transforms
let st = new ScaleTransform(ScaleX=5.0, ScaleY=5.0)
let tt = new TranslateTransform(X=(-40.0),Y=0.0)
let tg = new TransformGroup()
tg.Children.Add(st)
tg.Children.Add(tt)
//Create the TextBlock and set its transform
let tb = new TextBlock(Text=head.ToString(), Opacity=0.0, RenderTransform=tg,RenderTransformOrigin = new Point(0.5,0.5))
wordContainer.Children.Add(tb)
//Create the DoubleAnimations that specify how the text will animate,
//Darn Nullable types make this really ugly =/
let bt = TimeSpan.FromMilliseconds(1000.0 + delay * 30.0);
let duration = new Duration(TimeSpan.FromSeconds(0.1))
let opacityDA = new DoubleAnimation(From=Nullable(0.0), To=Nullable(1.0), Duration=duration, BeginTime=Nullable(bt))
let translateDA = new DoubleAnimation(From=Nullable(-40.0), To=Nullable(0.0), Duration=duration, BeginTime=Nullable(bt))
let scaleXDA = new DoubleAnimation(From=Nullable(5.0), To=Nullable(1.0), Duration=duration, BeginTime=Nullable(bt))
let scaleYDA = new DoubleAnimation(From=Nullable(5.0), To=Nullable(1.0), Duration=duration, BeginTime=Nullable(bt))
//Create a function that will hook the animation info to the storyboard.
let addToStoryboard doubleAni obj (propName:string) =
Storyboard.SetTarget(doubleAni, obj)
Storyboard.SetTargetProperty(doubleAni, new PropertyPath(propName))
storyboard.Children.Add(doubleAni)
addToStoryboard scaleXDA st "ScaleX"
addToStoryboard scaleYDA st "ScaleY"
addToStoryboard translateDA tt "X"
addToStoryboard opacityDA tb "Opacity"
//Parse the rest of the letters
parseLetters tail (delay+1.0) wordContainer wrapPanel
//Begin the recursion over the passed in string
let wrapPanel = new WrapPanel()
textboard.Children.Add(wrapPanel)
parseLetters (Seq.toList text) 0.0 (newWordContainer wrapPanel) wrapPanel
不要欺負自己:你只是想炫耀一些很酷的代碼! ;) – RCIX 2009-11-15 01:52:28
我沒有測試它,但就格式化/樣式而言,代碼本身看起來相當不錯。 – bcat 2009-11-15 02:10:31
我寫了一些C#代碼來做到這一點,即使邏輯非常相似,它大約是它的兩倍!我不能返回一個元組:( – rysama 2009-11-15 09:53:56