위와 같이 선이 그려지는 그리기 애니메이션을 생성하는 방법입니다.
파워포인트의 나타나기 효과로는 선이 그려지는 효과를 구현하기 어렵습니다.
파워포인트 2019 이상에서는 새로운 그리기 메뉴가 있고 여러가지 펜 및 잉크 기능이 소개되었습니다.
특히 잉크를 재생할 수 있는 Ink Replay 기능이 추가되었습니다.
이 잉크 재생기능을 활용해서 원하는 모양대로 화면에 선을 그어주는 애니메이션을 구현해보도록 하겠습니다.
만약 직선을 그리려면 잉크를 그릴 때 눈금자를 대고 직접 그려줄 수 있습니다.
Shift-F6 으로 눈금자 모드를 켜고 Alt+방향키로 15도씩 회전할 수 있습니다.
그런데 자를 대고 선을 긋는 것은 비효율적이고 자를 회전하는 것이 무척 번거로운 작업입니다.
그래서 미리 그려진 Freeform 도형을 따라서 잉크 도형을 추가하도록 해보았습니다.
첨부파일(Freeform2Ink.pptm)을 파일속성에서 '차단해제'하고 매크로 허용해서 열어주세요.
1. 먼저 빈슬라이드의 화면에 원하는 모양의 자유형(Freeform) 도형을 그려줍니다. 그리고 도형이름은 Freeform 1로 설정합니다.
현재로서는 직선이 적절하고 90도 각도가 아니고 다른 각도의 대각선(사선)이어도 됩니다.
선의 형태는 점선이 좋겠습니다. 나중에 안보이게 숨겨도 되겠습니다.
2. 그 다음 화면 바깥에 그리기 기능을 이용해서 잉크선을 하나 그려 놓습니다. 그리고 이름은 Ink_0으로 지정합니다. 이 잉크 그리기 개체가 없으면 복사할 수 없으므로 필수적입니다.
화면 바깥에 원하는 두께와 색상으로 직선 혹은 구불구불한 선으로 그려줍니다. 단색이나 화려한 무지개나 은하수색상도 가능합니다. 시작점과 끝점의 높이가 같게 만들어 주는 것이 좋습니다.
그리고 애니메이션에 '재생' 효과를 적용하고 시작:은 '이전 효과 다음에'로 그리고 재생시간을 0.25초~1초 등으로 설정합니다. 이 잉크선을 복사해서 자유형 도형의 node(점)을 따라서 각도와 크기를 조절해줄 예정입니다.
3. Alt-F8을 누르고 A1_Selection2Ink 매크로를 실행합니다.
4. 아래와 같이 Ink_0 이라는 기본 잉크 도형이 미리 그려놓은 Freeform 도형의 노드(점)을 따라서 여러 획으로 생성되었습니다. (VBA로 Ink모양을 추가할 때 InkML 이라는 InkXML 형식으로 잉크를 추가(Shapes.AddInkFromXML)할 수 있는 것 같은데 자세한 InkML 문법이 알려져 있지 않아 일단은 이렇게 기존 잉크를 복사해서 조절하는 방식으로 해결해보았습니다.)
은하수 색깔 잉크를 사용한 결과:
잉크의 두께를 조절하여 필압이 있는 것처럼 표현할 수도 있습니다.
기본 잉크를 구불구불한 선으로 만들면 아래와 같은 효과도 가능합니다.
실제 재생화면:
아주 복잡한 선도 잉크 그리기 애니메이션을 적용할 수 있습니다.
재생화면
이 방법을 한글이나 영어 글씨 선에 적용하여 마치 글씨를 쓰는 것처럼 글자 획을 따라서 잉크 그리기가 재생되도록 할 수 있습니다.
먼저 폰트를 하나의 선으로 긋는 것처럼 단선 path로 만들어 줘야 합니다. 그 방법은 아래 링크를 참고하세요.
https://konahn.tistory.com/entry/Font2Path
일러스트레이터에서 Image Trace(Line Art옵션)을 이용해서 선으로 바꾼 다음
해당 path를 복사하거나 SVG, EMF 등으로 저장해서 파워포인트에 그림으로 붙여 넣거나 불러온 다음
다시 우클릭해서 '그림 편집'을 누르고 오피스 도형으로 변환하고 그룹을 해제합니다.
그룹 해제 후 AutoShape 도형은 삭제해도 됩니다.
그 다음 모든 Freeform 도형들을 선택하고
Alt-F8을 누르고 다시 Freemform2Ink 매크로를 실행해서 선을 잉크로 변환합니다.
곡선을 제대로 표현하지 못하는 점이 아쉽습니다.
곡선부분을 더 세밀한 직선으로 표현한다면 좀 더 자연스럽겠습니다.
아래의 경우 Module2의 DrawRegPolygon 매크로를 이용해서 원(실제로는 32각형)을 자유형으로 넣고 나서 다시 잉크로 변환해보았습니다. 동그라미가 훨씬 자연스럽네요.
그리고 간혹 획의 방향이 오른쪽에서 시작하는 경우
일러스트레이터에서 해당 Path의 순서를 Reverse 해줘야 합니다.
아니면 파워포인트에서 간단히 도형방향을 좌우회전 시켜줘도 됩니다.
곡선 부분과 잉크 그리기 기능이 최신 버전에서만 지원된다는 점이 단점입니다.
이런 단점이 있지만
파워포인트에서 직접 그리는 듯한 애니메이션 효과를 구현할 수 있다는 점에서 의미가 있는 기능이라고 생각됩니다.
아울러서 오피스에서 지원되는 InkML 에 대한 더 자세한 예시와 구문 Syntax 문서가 공개, 지원되기를 바랍니다.
>> 재생 영상
>> 옵션 안내
Const ClearInk As Boolean = True '기존 잉크삭제 여부 Const AdjustSpeed As Boolean = True '잉크 애니메이션 속도를 길이에 맞게 조절 True이면 아래 기준 속도를 기준으로 길이가 길면 재생시간을 늘리지만 False로 두면 잉크 그리기 속도를 변경하지 않습니다. Const DefaultDuration As Single = 0.5 '기본 잉크 애니메이션 시간(속도) 코드상에 eft.Timing.Duration = DefaultDuration * shp.Width / 300 이 부분에서 300을 더 낮은 숫자로 바꾸면 애니메이션 속도가 낮아지고 더 높은 숫자로 하면 애니메이션이 더 빨라집니다. |
>> 매크로 기능
A1_Freeform2Ink : 자유형 도형을 따라 잉크 그리기를 생성
A2_RemoveInk: 현재 슬라이드의 모든 잉크 삭제
A3_DrawRegularPolygon: 원하는 각의 정다각형 생성(현재는 정32각형)
>> 핵심 코드 및 문제해결
- 가로 직선 잉크를 Freeform의 각 노드의 각도만큼 회전시키는 부분: node1 점과 node2 점의 각도를 삼각함수로 계산
- 회전하게 되면 기존 Left, Top 위치는 그대로인데 각도만 회전하여 보이는 Left, Top위치가 달라져서 이전 잉크선과 연결되지 않음.
- 회전으로 인해 이동한 만큼 Left, Top 위치를 보정해줘야 함 >> 삼각함수로 계산
- 잉크가 많아지면 약간 느려짐
>> VBA 코드
Option Explicit
Const Arad As Single = 57.2958
Const PI = 3.14159265358979
Const ClearInk As Boolean = True '기존 잉크삭제 여부
Const AdjustSpeed As Boolean = True '잉크 애니메이션 속도를 길이에 맞게 조절
Const DefaultDuration As Single = 0.5 '기본 잉크 애니메이션 시간(속도)
Sub Selection2Ink()
Dim oShp As Shape
Dim oRng As ShapeRange
Dim oSld As Slide
On Error Resume Next
Set oSld = ActiveWindow.View.Slide
If oSld Is Nothing Then MsgBox "No slide selected.": Exit Sub
Set oRng = ActiveWindow.Selection.ShapeRange
If oRng Is Nothing Then
Set oShp = FindShape("Freeform 1")
If oShp Is Nothing Then MsgBox "No 'Freeform' shape": Exit Sub
oShp.Select
Set oRng = ActiveWindow.Selection.ShapeRange
End If
If oRng.Count = 0 Then MsgBox "Select one or more 'Freeform' shape": Exit Sub
On Error GoTo 0
If ClearInk Then RemoveInk oSld
For Each oShp In oRng
If oShp.Type = msoFreeform Then If Freeform2Ink(oShp) = -1 Then Exit For
Next oShp
If AdjustSpeed Then Call AdjustInkSpeed(oSld)
End Sub
Function Freeform2Ink(shp As Shape) As Integer
Dim ink As Shape, inkd As Shape
Dim sld As Slide
Dim n1 As ShapeNode, n2 As ShapeNode
Dim x1!, y1!, x2!, y2!, w!, r!, x!, y!, Rad!
Dim i As Integer
If shp.Type <> msoFreeform Then MsgBox "The selected shape is not a Freeform": Exit Function
Set sld = shp.Parent
Set ink = FindShape("Ink_0")
If ink Is Nothing Then MsgBox "The default ink shape(Ink_0) not found": Freeform2Ink = -1: Exit Function
For i = 1 To shp.Nodes.Count - 1
'duplicate the default ink
Set inkd = ink.Duplicate(1)
inkd.Name = "Ink_" & shp.ZOrderPosition & "_" & i
DoEvents
'get each node
Set n1 = shp.Nodes(i)
x1 = n1.Points(1, 1)
y1 = n1.Points(1, 2)
Set n2 = shp.Nodes(i + 1)
x2 = n2.Points(1, 1)
y2 = n2.Points(1, 2)
'adjust the location, width and rotation of the copied ink
w = Sqr((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
inkd.Width = w
'get the rotation angle
If x2 - x1 = 0 And y2 >= y1 Then
r = 90
ElseIf x2 - x1 = 0 And y2 < y1 Then
r = 270
Else
r = Atn((y2 - y1) / (x2 - x1)) * Arad
If x2 < x1 Then r = 180 + r
End If
inkd.Left = x1
inkd.Top = y1
inkd.Rotation = r
Rad = (PI / 180) * r
y = Sin(Rad) * w / 2
x = w / 2 - Cos(Rad) * w / 2
inkd.Left = x1 - x
inkd.Top = y1 + y
Debug.Print i; ; x1, y1, x2, y2, w, r, inkd.Rotation, x, y
Next i
Freeform2Ink = 1
End Function
'Ink 의 길이에 따라서 애니메이션 길이 조절
Function AdjustInkSpeed(sld As Slide)
Dim shp As Shape
Dim eft As Effect
For Each shp In sld.Shapes
If shp.Type = msoInkComment And shp.Name Like "Ink_*" Then
Set eft = sld.TimeLine.MainSequence.FindFirstAnimationFor(shp)
If Not eft Is Nothing Then
eft.Timing.Duration = DefaultDuration * shp.Width / 300
End If
End If
Next shp
End Function
'remove all of the old ink shapes
Function RemoveInk(oSld As Slide)
Dim i As Long
For i = oSld.Shapes.Count To 1 Step -1
If oSld.Shapes(i).Name Like "Ink_*" And oSld.Shapes(i).Name <> "Ink_0" Then _
oSld.Shapes(i).Delete
Next i
End Function
'find and return the shape with the given name
Function FindShape(shpName As String) As Shape
Dim oSld As Slide
Dim oShp As Shape
Set oSld = ActiveWindow.View.Slide
For Each oShp In oSld.Shapes
If oShp.Name Like shpName Then
Set FindShape = oShp
Exit For
End If
Next oShp
End Function
>> 샘플 포함 VBA 파일
>> 관련: 지식인
'PPT+VBA' 카테고리의 다른 글
PPT 일부 슬라이드만 블러처리된 그림 프레젠이션 만들기 (1) | 2024.04.28 |
---|---|
물결무늬 선 만들기 (2) | 2024.04.05 |
폴더 내의 모든 pptx파일의 모든 슬라이드를 png로 내보내기 (0) | 2024.04.02 |
편집 모드에서 자동으로 동영상 재생 (0) | 2024.03.13 |
100슬라이드 중 랜덤(무작위) 5슬라이드 재생 (1) | 2024.01.19 |
테이블(표) 윤곽선 따라 가이드 선 자동 추가 (1) | 2024.01.15 |
시간 제한 퀴즈 게임 템플릿 (1) | 2024.01.01 |
폴더 내의 모든 PPT를 PDF로 일괄로 내보내기 (0) | 2023.12.17 |
최근댓글