파워포인트에서 도형에 이동경로 애니메이션효과를 추가하고 나서
마우스로 이동위치를 정확히 맞춰서 수정하기 힘든 경우가 많습니다. 이때는 VBA를 이용하여 이동 좌표를 수정할 수 있습니다. 파워포인트에서 이동경로 애니메이션 효과에는 내부적으로 VML 이라는 문법 혹은 명령어 규칙이 사용됩니다.
VML 이란?
VML 은 Vector Markup Language 의 줄임말입니다. 벡터 Vector는 비트맵처럼 일련의 점색깔로 이미지를 표현하지 않고 두 점간에 선을 그어서 이미지를 표현하는 방식으로 확대나 대형 출력에 효과적입니다. 요즘에 많이 쓰이는 SVG 이미지가 이에 해당합니다. SVG(Scalable Vector Graphic)이미지는 jpg/png같은 별도의 비트맵 이미지 없이 HTML문서 내에 VML명령어를 넣어서 화면에 나타낼 수도 있습니다.
그런데 온라인 상에 VML에 관한 입문자용 기초 정보가 거의 없다시피하여 이번 기회에
복잡할 수 있지만 VML의 간단한 기초 문법과 VBA를 이용한 수정 방법을 좀 안내드리겠습니다.
파워포인트 VML에 쓰이는 좌표방식
파워포인트 VML의 좌표방식은 전체 슬라이드 크기를 1로 보고 그에 대한 비율 혹은 소수점 수치입니다.
x좌표로 본다면 왼쪽이 0이고 오른쪽 끝이 1이고 가운데 슬라이드 중앙은 0.5입니다.
슬라이드를 벗어난 위쪽이나 왼쪽은 마이너스 좌표가 됩니다.
VML 경로(Path) 기초 명령어(Command)1 - 직선 이동
자주 쓰이는 명령어 M , L/ C, E/ Z 등입니다. M은 MoveTo 이동을 시작한다는 의미이고 L은 LineTo 직선이동, 마지막 E는 End 끝(열린 경로는 E, 닫힌 경로는 Z, 생략되기도 함)이라는 의미입니다.
만일 맨 왼쪽 상단의 둥근 원이 오른쪽 아래 대각선 방향으로 중간점 위치(0.5,0.5)로 이동한다면
VML 코드 및 좌표는 아래와 같습니다.
M 0 0 L 0.5 0.5 E
슬라이드 중앙에 있는 원이 오른쪽 아래 대각선 방향으로 이동한다고 해도 이동경로값은 위와 같습니다.
M 다음의 좌표값은 화면상의 좌표가 아니고 출발점 기준의 상대적인 좌표입니다. M 0 0 은 도형의 현재 위치에서 그대로 출발한다는 뜻입니다. 경로 편집을 하지 않는 한 대개는 M 0 0 으로 시작합니다. (M 0.5 0.5 는 현재 도형의 위치로부터 슬라이드 절반만큼 대각선으로 이동한 위치에서 출발합니다.) 아래 그림의 두 원에 적용된 이동경로 값은 똑같습니다.
※ 대개는 출발점 (0,0)이 다음에 나오는 모든 좌표의 기준점이 되고 그 다음 이동 좌표값(들)은 이 출발기준점으로 부터의 상대적인 거리값으로 표현합니다. 그런데 이동 명령어가 l, c 등 소문자인 경우는 기준점이 처음 출발점이 아니라 이전 좌표가 됩니다. 파워포인트에서 만들어진 이동경로는 출발점 기준의 좌표를 사용합니다. VBA로는 이동경로를 이전 위치를 기준으로 한 상대좌표로 사용할 수 있습니다. 실제 좌표를 계산할 때는 번거롭지만 경우에 따라서 이동시 상대좌표를 쓰는 것이 간단하고 효율적일 수도 있습니다.
직선이동시 좌표를 일치시키기
만약 원 도형이 화면의 1/4 지점(0.25, 0.25)까지 대각선으로 이동하고 다시 1/4만큼 아래로 이동하는 경우
최근 파워포인트 버전에서는 마우스로 도형이동선을 편집할 때 점의 위치가 이전 위치와 가까우면
자동으로 맞춰주는데 여기서는 이해를 위해 아래 그림처럼 조금 어긋났다고 가정하겠습니다.
그 때 추가된 VML코드는 아래와 같을 것입니다.
첫번째: M 0 0 L 0.25 0.25 E
두번째: M 0.28229 0.25 L 0.28229 0.5 E
이 상태에서 두번째 이동 애니메이션의 시작위치를 이전 애니메이션의 마지막 지점으로 동일하게 만들려면 아래처럼 두번째 이동 애니메이션 시작 좌표를 일치시키고 기타 경로를 아래처럼 수정해주면 됩니다.
첫번째: M 0 0 L 0.25 0.25 E
두번째: M 0.25 0.25 L 0.25 0.5 E (처음 출발점 0 0 기준으로 대각선으로 0.25만큼 이동한 출발점)
두번째 경로를 아래처럼 상대좌표 방식으로 표현하면 좀 더 간단할 수 있습니다.
첫번째: M 0 0 L 0.25 0.25 E
두번째: M 0.25 0.25 l 0 0.25 E (m은 시작기준점인데 L을 소문자 l로 쓰면 이전 기준점으로 부터 상대좌표로 이동)
두 번의 애니메이션 이동경로를 한번의 경로로 연결할 수도 있습니다.
M 0 0 L 0.25 0.25 L 0.25 0.5 E (처음 출발점 0 0이 모든 이동경로의 기준이 됨)
혹은
M 0 0 L 0.25 0.25 l 0 0.25 E (명령어가 소문자이면 이전 위치 (0.25, 0.25)가 이동경로의 기준이 됨)
VBA에서 현재 도형의 이동경로를 확인하거나 다른 수치값으로 편집하려면 아래와 같습니다.
M 0 0 L 0.25 0.25 E M 0.28229 0.25 L 0.28229 0.5 E
이 상태에서 두번째 이동 애니메이션의 시작위치를 이전 애니메이션의 마지막 지점으로 동일하게 만들려면 아래처럼 두번째 이동 애니메이션 시작 좌표와 경로를 아래처럼 수정해주면 됩니다.
M 0 0 L 0.25 0.25 E M 0.25 0.25 L 0.25 0.5 E
VBA에서 이동경로 편집 코드는 아래와 같습니다.
'도형의 이동효과에 걸린 VML Path 를 모두 표시
Sub ViewPath()
Dim sld As Slide
Dim shp As Shape
Dim i As Long
Dim j As Long
Set sld = ActiveWindow.Selection.SlideRange(1) '현재 슬라이드
'MainSequence
For i = 1 To sld.TimeLine.MainSequence.Count
With sld.TimeLine.MainSequence.Item(i)
'현재 선택된 도형이면
'If .Shape Is ActiveWindow.Selection.ShapeRange(1) Then
For j = 1 To .Behaviors.Count
If .Behaviors.Item(j).Type = msoAnimTypeMotion Then _
Debug.Print .Behaviors.Item(j).MotionEffect.Path
Next j
'End If
End With
Next i
End Sub
'도형의 이동효과에 걸린 VML Path 를 사용자 입력대로 수정
Sub ChangePath()
Dim sld As Slide
Dim shp As Shape
Dim i As Long
Dim j As Long
Dim newPath As String
Set sld = ActiveWindow.Selection.SlideRange(1) '현재 슬라이드
On Error Resume Next
If ActiveWindow.Selection.ShapeRange.Count = 0 Then _
MsgBox ("먼저 이동경로가 설정된 도형을 선택하세요."): Exit Sub
On Error GoTo 0
'MainSequence
For i = 1 To sld.TimeLine.MainSequence.Count
With sld.TimeLine.MainSequence.Item(i)
'현재 선택된 도형이면
If .Shape Is ActiveWindow.Selection.ShapeRange(1) Then
For j = 1 To .Behaviors.Count
If .Behaviors.Item(j).Type = msoAnimTypeMotion Then
newPath = InputBox("바꿀 VML Path 를 입력하세요:", Default:= _
.Behaviors.Item(j).MotionEffect.Path)
If newPath <> "" Then _
.Behaviors.Item(j).MotionEffect.Path = newPath
End If
Next j
End If
End With
Next i
'InteractiveSequence 트리거 애니메이션의 경우
' For Each seq In sld.TimeLine.InteractiveSequences
' For i = 1 To seq.Count
' If seq(i).Shape Is ActiveWindow.Selection.ShapeRange(1) Then
' For j = 1 To seq(i).Behaviors.Count
' If seq(i).Behaviors(j).Type = msoAnimTypeMotion Then
' newPath = InputBox("바꿀 VML Path 를 입력하세요:", Default:= _
' seq(i).Behaviors(j).MotionEffect.Path)
' If newPath <> "" Then _
' seq(i).Behaviors(j).MotionEffect.Path = newPath
'
' End If
' Next j
' End If
' Next i
' Next seq
End Sub
테스트 해보려면 첨부파일(매크로 허용해서 열기)의 특정 슬라이드에서
원도형을 선택하고 Alt-F8누르고 ChangePath 매크로를 실행하면
현재 선택된 도형의 이동 경로를 편집할 수 있습니다.
2개의 이동 애니메이션이 적용된 경우 편집 대화창이 2번 뜨게 됩니다.
VML 경로(Path) 기초 명령어(Command)2 - 곡선 이동
여기까지는 L 즉 직선이동인 경우만 예시로 들었는데 C 즉 곡선 이동일 때는 좌표가 시작점과 마지막 점의 x,y 뿐만 아니라 조절점의 x,y 좌표가 더 추가됩니다. 아래처럼 조절점 좌표 그리고 두번째 조절점 그리고 마지막 좌표 이렇게 좌표값이 3개 세트가 추가됩니다. 슬라이드에서 이동경로 점편집을 해보면 조절점이 왜 필요한지 알 수 있습니다. (예전에 당시 닉네임 Pizo님이 슬라이드쇼상에서 곡선을 편집하는걸 구현했었는데 그때 마우스로 조절점을 이리저리 움직여서 곡선을 조절했던 것과 비슷합니다.)
M 0 0 C 0.5 0 0.5 0 0.5 0.5
C 다음에 (0.5,0) 이 첫번째 조절점(이동경로 점편집에서 점을 선택할 때 보이는 화면상의 흰색 작은 네모 위치)이고
두번째 (0.5,0)이 두번째 조절점입니다. 마지막 (0.5, 0.5)가 마지막 이동 위치가 되겠습니다. 곡선은 이렇게 조절점 좌표 2개를 추가로 이용해 곡선의 모양이 달라지게 됩니다. (최근에는 조절점을 더 추가해서 곡선을 더 정교하게 그리기도 합니다. 폰트파일 중 OTF 가 그런 방식으로 3차원 베지어 곡선 기술을 이용한다고 들었습니다.) 만일 조절점을 따로 멀리 두지 않으려면 기존 좌표 위치와 동일하게 써주면 곡선이지만 직선처럼 됩니다.
아래는 두번의 곡선 이동경로가 추가된 예시입니다.
M 0 0 C 0 0 0.5 0 0.5 0.5 C 0.5 1 1 1 1 1
시작좌표의 시작 조절점과 마지막좌표의 두번째 조절점은 점의 좌표와 동일하고
추가로 (0.5,0) 그리고 (0.5,1) 두개의 조절점이 곡선을 만드는데 주된 역할을 하고 있습니다.
조절점 좌표값을 바꿔보면 곡선의 원리를 조금이나마 느끼실 수 있습니다.
VML 문법에 명령어(command)는 L과 C 외에도 많지만 주로 쓰는 용도로는 이 정도가 적당하다고 봅니다.
더 많은 Path 명령어는 링크를 참고하세요.
VML경로를 수정하는 과정은 캡쳐영상을 확인하세요.
( 그리고 지금까지 일반 애니메이션(MainSequence)을 위주로 설명했는데 만약 트리거 애니메이션(InterActiveSequence)이 걸린 이동 경로인 경우 코드가 조금 달라집니다. 트리거 애니메이션의 이동 경로 편집은 위의 코드의 주석처리된 부분의 주석을 해제하면 됩니다. )
이동경로 애니메이션 후 마지막 위치 구하기
추가로 현재 이동경로가 적용된 도형에
현재슬라이드나 다음슬라이드에 다시 한번 이동 경로를 추가하고 싶을 때
기존 도형의 애니메이션 후 마지막 위치를 구하기가 힘든데,
그 때 위에서 설명한 VML 경로에 대한 규칙을 응용하면 됩니다.
기존 슬라이드의 원하는 도형의 VML 경로상의 맨 마지막 좌표(소수점 형태)를
파워포인트 슬라이드상의 pt 좌표로 바꿔서
해당 도형을 애니메이션 후 마지막 위치로 정확히 이동시켜줄 수 있습니다.
먼저 실행방법과 실행화면입니다.
첨부한 파일을 매크로를 허용해서 엽니다.
그리고 이동경로가 있는 도형을 선택한 상태에서 개발도구-매크로나 단축키 Alt-F8을 누르고
Jump2LastPosition을 실행합니다.
그러면 선택된 도형을 이동경로상의 마지막 이동경로 위치를 소수점 비율좌표값에서 슬라이드 절대값위치로 계산하여 정확히 복사/이동시켜줍니다.
내부 로직 순서는
마지막 이동경로 문자열을 구한 뒤 스페이스로 구분하여 Split 처리하고나서
맨 뒤에서 부터 숫자인 경우를 만나면 마지막 두 개의 숫자를 구해서 y좌표와 x좌표를 차례로 구할 수 있습니다.
이 두 좌표를 각각 슬라이드 넓이와 높이로 곱해주면
슬라이드상의 pt 좌표로 변환이 됩니다.
마지막좌표에서 시작위치를 감안해서 변환한 값에서 도형의 넓이와 높이의 절반 만큼 빼서
복사된 도형의 Left, Top 값에 적용하여 마지막 위치의 정가운데에 도형을 이동키는 원리입니다.
(현재는 마지막 좌표가 출발점 기준으로 이동하는 경우(대문자 L, C command)를 가정했는데 만약 이전좌표를 기준으로 한 상대적인 이동좌표(소문자 l, c command)라면 이전 좌표위치만큼 추가로 보정해줘야 함.)
자세한 코드는 아래와 같습니다.
Sub Jump2LastPosition()
Dim sld As Slide
Dim shp As Shape
Dim i As Long, j As Long
Dim newPath As String
Dim pos() As String
Dim x0 As Single, y0 As Single, x As Single, y As Single, SW As Single, SH As Single
Set sld = ActiveWindow.Selection.SlideRange(1) '현재 슬라이드
On Error Resume Next
If ActiveWindow.Selection.ShapeRange.Count = 0 Then _
MsgBox ("먼저 이동경로가 설정된 도형을 선택하세요."): Exit Sub
On Error GoTo 0
Set shp = ActiveWindow.Selection.ShapeRange(1)
'MainSequence
For i = 1 To sld.TimeLine.MainSequence.Count
With sld.TimeLine.MainSequence.Item(i)
'현재 선택된 도형이면
If .Shape Is shp Then
For j = 1 To .Behaviors.Count
If .Behaviors.Item(j).Type = msoAnimTypeMotion Then
newPath = .Behaviors.Item(j).MotionEffect.Path
End If
Next j
End If
End With
Next i
'Path 조각내기
pos() = Split(newPath, " ")
'시작 좌표 구하기 (여기서는 사용되지 않음)
For i = 0 To UBound(pos)
If IsNumeric(pos(i)) Then
x0 = CSng(pos(i))
y0 = CSng(pos(i + 1))
Exit For
End If
Next
'마지막 좌표 구하기
For i = UBound(pos) To 0 Step -1
If IsNumeric(pos(i)) Then
y = CSng(pos(i))
x = CSng(pos(i - 1))
Exit For
End If
Next
'슬라이드 가로, 세로 길이 구하기
With ActivePresentation.PageSetup
SW = .SlideWidth
SH = .SlideHeight
End With
'도형 복사 후 변환된 좌표로 이동하고 가운데로 위치시킴
With shp.Duplicate(1)
.Left = (x + (shp.Left + shp.Width / 2) / SW) * SW - .Width / 2
.Top = (y + (shp.Top + shp.Height / 2) / SH) * SH - .Height / 2
End With
Set shp = sld.Shapes(sld.Shapes.Count)
'현재 도형에 걸린 기존 이동 효과 삭제
For i = sld.TimeLine.MainSequence.Count To 1 Step -1
With sld.TimeLine.MainSequence(i)
If .Shape Is shp Then
For j = .Behaviors.Count To 1 Step -1
If .Behaviors.Item(j).Type = msoAnimTypeMotion Then .Behaviors.Item(j).Delete
Next j
End If
If .Behaviors.Count = 0 Then .Delete
End With
Next i
End Sub
이동경로 효과가 적용된 도형의 마지막 위치에 다시 도형을 위치시키고 싶다면
첨부파일 연 상태에서 자신의 파일을 열고
Alt-F8 누르고 매크로 위치를 첨부파일로 선택하고 Jump2LastPosition 실행만하면
도형을 마지막 위치로 복사해주기 때문에
복사된 도형에 추가 이동경로를 추가하거나
다른 슬라이드에 붙여넣고 애니메이션을 이어서 추가할 수도 있겠습니다.
VML 이동 경로의 활용방안
- 별모양, 팔각형 등 특정 Autoshape 모양으로 원하는 도형이 이동하게 만들 수 있음.
- 도형이 일반 AutoShape인 경우는 사각테두리 좌표만 알기때문에 도형의 각 꼭지점의 좌표를 알기 어렵지만 BuildFreeform 등을 이용해서 만든 Node방식의 Freeform 도형인 경우는 각 node가 x, y 좌표방식이라 이동경로 좌표로 변환하면 되기 때문에 쉽게 도형을 따라 다른 도형이 이동하게 만들 수 있음.
- 서명처럼 잉크나 펜으로 입력한 경로를 따라서 도형이 이동하게 만들 수 있음.
- 파워포인트에서 자체적으로 지원하는 않는 이동 경로를 추가할 수 있음. 예를 들어 당구공이 튕기는 애니메이션이나 포탄이 포물선으로 날아가는 애니메이션.
- 도형에 트리거를 걸어서 클릭시 특정 위치로 이동하게 할 때 제한된 기본 애니메이션을 이용하지 않고 상대좌표 방식 VML을 이용하여 도형을 원하는 위치로 효율적으로 이동하게 할 수 있음.
- 복잡하게 이동하는 사용자지정애니메이션의 경우도 VML Path를 수정하여 일괄로 수정할 수 있음. (예시)
- 곡선이동을 직선이동으로 또는 반대로 수정할 수 있음.
VML 이동경로 편집을 위한 VBA샘플 파일 다운로드
- 직선 및 곡선 이동경로 편집과 이동경로상 마지막 위치로 도형 복사하는 테스트용 pptm 파일 다운로드 받으세요.
- 직선, 곡선, 절대경로, 상대경로, 하트모양 등 간단한 이동 애니메이션 예제가 들어 있습니다.
pptm 파일은 다운로드 받으면 파일 속성에서 차단해제 체크하고 적용/확인하세요.
열 때 매크로 컨텐츠 허용 버튼이 뜨면 꼭 눌러주어야 매크로가 실행 가능합니다.
'PPT+VBA' 카테고리의 다른 글
PPT 슬라이드내의 글자 사용빈도 통계 (0) | 2021.09.12 |
---|---|
그림효과 복사 일괄적용 (0) | 2021.09.12 |
파워포인트 파일을 저장 후 다시 열 때 읽기전용 (Read Only) 로 바뀌는 경우 (0) | 2021.09.08 |
슬라이드 번호를 특정 페이지부터 시작 (6) | 2021.08.09 |
RGB Color Constants, VBA RGB 색상 예약어 목록 (0) | 2021.07.04 |
pptx의 내용에 문제가 있습니다. 프리젠테이션 복구가 시도될 수 있습니다. (0) | 2021.06.26 |
사진 일괄 삽입 매크로 (3) | 2021.06.08 |
텍스트상자와 배경도형 정렬 (0) | 2021.05.31 |
최근댓글