Джон Исон уже исправил вашу проблему, но если вам нужен рабочий фрагмент, вот один:
РЕДАКТИРОВАТЬ : вам не нужно добавлять какие-либо элементы управления в форму, просто скопируйте ивставьте фрагмент.
Option Explicit
'*****************************************************************
'Author: https://stackoverflow.com/users/4938616/david
'Source: https://stackoverflow.com/q/53993968/4938616
'*****************************************************************
Private WithEvents tmrAnim As Timer
Private fraContainer As Frame
Private WithEvents btnStart As CommandButton
Private Sub btnStart_Click()
Static dir_switch As Boolean
'runs animation
Call runAnim(dir_switch)
'toggles the direction of the animation
dir_switch = Not dir_switch
End Sub
'Call this function from wherever you need to trigger the animation
Private Sub runAnim(ByVal runBackwards As Boolean)
Call timerCallback(-1, runBackwards)
tmrAnim.Enabled = True
End Sub
'timer event that updates the key frames
Private Sub tmrAnim_Timer()
Static key As Long
'function returns true when the it's done with the animation
'it is provided with a keyframe
If timerCallback(key) Then
key = 0
tmrAnim.Enabled = False
End If
'keyframe update
key = key + 1
End Sub
'this function is called from the timer and does the actual animation
Private Function timerCallback(ByRef key As Long, Optional ByRef runBack As Boolean = False) As Boolean
Static backwardAnim As Boolean 'determines the direction the animation should occur
'When key is negative this function is being called to set up its forwardAnim variable.
'This is not a clean solution, it's just a quick workaround
If key < 0 Then
backwardAnim = runBack
Exit Function
End If
'variables that keep track of animation flow
Dim kLeft As Long, kWidth As Long
'constants that store the ranges for the animation
'these could be global, but I don't like global variables
Const INI_LEFT As Long = 10, END_LEFT As Long = 170
Const INI_WIDTH As Long = 320, END_WIDTH As Long = 160
'determines the last key frame in the animation (inclusive)
Const MAX_KEY As Long = 8
Dim progress As Single
'determines the direction of the animation progress
If Not backwardAnim Then
progress = key / MAX_KEY
Else
progress = (MAX_KEY - key) / MAX_KEY
End If
'This is just a linear function of the form "c = a - (a - b) * n"
'where a and b are two arbitrary points, and c is any point in between
'a and b when 0 <= n < 1
fraContainer.Left = INI_LEFT - (INI_LEFT - END_LEFT) * progress
fraContainer.Width = INI_WIDTH - (INI_WIDTH - END_WIDTH) * progress
'returns value to caller (timer) to determine when to stop
timerCallback = key = MAX_KEY
End Function
'Inititalizes the controls added programmatically
'it's here to the bottom because it's not relevant for the purposes of this example
Private Sub Form_Load()
Set tmrAnim = Me.Controls.Add("VB.Timer", "tmrAnim", Me)
Set fraContainer = Me.Controls.Add("VB.Frame", "fraContainer", Me)
Set btnStart = Me.Controls.Add("VB.CommandButton", "btnStart", fraContainer)
Me.ScaleMode = vbTwips
Me.Width = (Me.Width - Me.ScaleWidth) + 340 * VB.Screen.TwipsPerPixelX
Me.Height = (Me.Height - Me.ScaleHeight) + 260 * VB.Screen.TwipsPerPixelY
Me.ScaleMode = vbPixels
'Initialize timer object properties
With tmrAnim
.Interval = 16 'cycles ~ every 25 milliseconds
.Enabled = False
End With
'Initialize frame object properties
With fraContainer
.Caption = "Placeholder text"
.Move 10, 10, 320, 240
.Visible = True
End With
'Initialize CommandButton object properties
With btnStart
.Default = True
.Caption = "Start Animation"
'This button's parent is a frame and frames don't inherit or can change their scale mode.
'Default are Twips which are 8 times bigger than pixels
.Move 10 * VB.Screen.TwipsPerPixelX, 20 * VB.Screen.TwipsPerPixelX, 120 * VB.Screen.TwipsPerPixelX, 20 * VB.Screen.TwipsPerPixelX
.Visible = True
End With
End Sub
- Таймер, который генерирует ключевые кадры
- В событии таймера я вызываю
timerCallback
, который получает ключевой кадр и управляет анимацией - Константы в
timerCallback
контролируют начало и конец анимации, а также сколько ключевых кадров будет - Таймер включается функцией под названием
runAnim
runAnim
можно вызвать из любого места, где вы хотите включить анимацию.