Skip to content

Commit 3e6902e

Browse files
committed
Added Export Feature(Pending cleanup)
1 parent 9f475c9 commit 3e6902e

12 files changed

+341
-194
lines changed

OpenBoardAnim/DLLs/ffmpeg.exe

83.4 MB
Binary file not shown.

OpenBoardAnim/DLLs/ffplay.exe

83.2 MB
Binary file not shown.

OpenBoardAnim/DLLs/ffprobe.exe

83.2 MB
Binary file not shown.

OpenBoardAnim/OpenBoardAnim.csproj

+9
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@
4242
</ItemGroup>
4343

4444
<ItemGroup>
45+
<None Update="DLLs\ffmpeg.exe">
46+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
47+
</None>
48+
<None Update="DLLs\ffplay.exe">
49+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
50+
</None>
51+
<None Update="DLLs\ffprobe.exe">
52+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
53+
</None>
4554
<None Update="Resources\peep-102.svg">
4655
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
4756
</None>

OpenBoardAnim/Services/PubSubService.cs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public enum SubTopic
88
SceneChanged,
99
GraphicAdded,
1010
ProjectLaunched,
11+
ProjectExporting
1112
}
1213

1314
public interface IPubSubService

OpenBoardAnim/Utils/PathAnimationExample.cs

-116
This file was deleted.
+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
using OpenBoardAnim.Models;
2+
using System.Windows;
3+
using System.Windows.Controls;
4+
using System.Windows.Media;
5+
using System.Windows.Media.Animation;
6+
using System.Windows.Shapes;
7+
8+
namespace OpenBoardAnim.Utils
9+
{
10+
public class PathAnimationHelper
11+
{
12+
private Canvas _canvas;
13+
private List<Path> _paths;
14+
private GraphicModelBase _graphic;
15+
private UIElement _hand;
16+
List<double> _lengths = new List<double>();
17+
public TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
18+
public PathAnimationHelper(Canvas canvas,
19+
List<Path> paths,
20+
GraphicModelBase graphic,
21+
UIElement hand)
22+
{
23+
_canvas = canvas;
24+
_paths = paths;
25+
_graphic = graphic;
26+
foreach (var path in _paths)
27+
{
28+
double item = GetTotalLength((PathGeometry)path.Data);
29+
_lengths.Add(item);
30+
// Set up the dash array and offset
31+
path.StrokeDashArray = new DoubleCollection(new double[] { item });
32+
path.StrokeDashOffset = item;
33+
}
34+
35+
_hand = hand;
36+
Canvas.SetLeft(_hand, _graphic.X);
37+
Canvas.SetTop(_hand, _graphic.Y);
38+
}
39+
public async void AnimatePathOnCanvas()
40+
{
41+
Storyboard storyboard = new();
42+
TimeSpan beginTime = TimeSpan.Zero;
43+
for (int i = 0; i < _paths.Count; i++)
44+
{
45+
Path path = _paths[i];
46+
// Add the path to the canvas
47+
_canvas.Children.Add(path);
48+
Canvas.SetLeft(path, _graphic.X);
49+
Canvas.SetTop(path, _graphic.Y);
50+
double ratio = _lengths[i] / _lengths.Sum();
51+
// Create the animation
52+
TimeSpan timeSpan = TimeSpan.FromSeconds(_graphic.Duration * ratio);
53+
DoubleAnimation dashOffsetAnimation = new DoubleAnimation
54+
{
55+
From = _lengths[i],
56+
To = 0,
57+
Duration = timeSpan,
58+
BeginTime = beginTime
59+
};
60+
61+
// Create the animation
62+
MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath
63+
{
64+
PathGeometry = (PathGeometry)path.Data,
65+
Duration = timeSpan,
66+
BeginTime = beginTime
67+
};
68+
beginTime += timeSpan;
69+
// Create a MatrixTransform for the ellipse
70+
MatrixTransform matrixTransform = new MatrixTransform();
71+
_hand.RenderTransform = matrixTransform;
72+
DependencyProperty[] propertyChain = [UIElement.RenderTransformProperty, MatrixTransform.MatrixProperty];
73+
string thePath = "(0).(1)";
74+
PropertyPath myPropertyPath = new(thePath, propertyChain);
75+
// Start the animation
76+
Storyboard.SetTarget(matrixAnimation, _hand);
77+
Storyboard.SetTargetProperty(matrixAnimation, myPropertyPath);
78+
Storyboard.SetTarget(dashOffsetAnimation, path);
79+
Storyboard.SetTargetProperty(dashOffsetAnimation, new PropertyPath(Shape.StrokeDashOffsetProperty));
80+
storyboard.Children.Add(matrixAnimation);
81+
storyboard.Children.Add(dashOffsetAnimation);
82+
}
83+
storyboard.Completed += DashOffsetAnimation_Completed;
84+
storyboard.Begin();
85+
86+
await Task.CompletedTask;
87+
}
88+
private void DashOffsetAnimation_Completed(object sender, EventArgs e)
89+
{
90+
Canvas.SetLeft(_hand, 2000);
91+
Canvas.SetTop(_hand, 1100);
92+
tcs?.TrySetResult(true);
93+
}
94+
95+
// Helper method to calculate total length of the geometry
96+
private static double GetTotalLength(PathGeometry geometry)
97+
{
98+
double length = 0;
99+
foreach (PathFigure figure in geometry.Figures)
100+
{
101+
Point start = figure.StartPoint;
102+
foreach (PathSegment segment in figure.Segments)
103+
{
104+
if (segment is LineSegment line)
105+
{
106+
length += (line.Point - start).Length;
107+
start = line.Point;
108+
}
109+
else if (segment is PolyLineSegment polyLine)
110+
{
111+
foreach (Point point in polyLine.Points)
112+
{
113+
length += (point - start).Length;
114+
start = point;
115+
}
116+
}
117+
// Add cases for other segment types if needed
118+
}
119+
}
120+
return length;
121+
}
122+
}
123+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
using OpenBoardAnim.Models;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
using System.Windows.Controls;
9+
using System.Windows.Media;
10+
using System.Windows.Media.Imaging;
11+
using System.Windows.Shapes;
12+
13+
namespace OpenBoardAnim.Utils
14+
{
15+
public class PreviewAndExportHandler
16+
{
17+
public static async Task RunAnimationsOnCanvas(ProjectDetails project, Canvas canvas, bool isExport)
18+
{
19+
if (project != null)
20+
{
21+
Image hand = new()
22+
{
23+
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/pencil.png"))
24+
};
25+
VideoExporter exporter = null;
26+
if (isExport)
27+
{
28+
exporter = new(canvas, 30);
29+
exporter.StartCapture();
30+
}
31+
int index = 1;
32+
for (int i = 0; i < project.Scenes.Count - 1; i++)
33+
{
34+
canvas.Children.Clear();
35+
canvas.Children.Add(hand);
36+
Canvas.SetLeft(hand, 0);
37+
Canvas.SetTop(hand, 1150);
38+
Canvas.SetZIndex(hand, 1);
39+
SceneModel scene = project.Scenes[i];
40+
if (scene != null)
41+
{
42+
for (int j = 0; j < scene.Graphics.Count; j++)
43+
{
44+
GraphicModelBase graphic = scene.Graphics[j];
45+
await Task.Delay((int)graphic.Delay * 1000);
46+
List<Path> paths = [];
47+
Geometry geometry = null;
48+
UIElement element = null;
49+
if (graphic is DrawingModel drawing)
50+
{
51+
DrawingGroup drawingGroup = drawing.ImgDrawingGroup.Clone();
52+
drawingGroup.Transform = new ScaleTransform(drawing.ResizeRatio, drawing.ResizeRatio);
53+
geometry = GeometryHelper.ConvertToGeometry(drawingGroup);
54+
element = new Image
55+
{
56+
Source = new DrawingImage(drawingGroup)
57+
};
58+
}
59+
else if (graphic is TextModel text)
60+
{
61+
geometry = text.TextGeometry;
62+
element = new TextBlock()
63+
{
64+
Text = text.RawText,
65+
Foreground = Brushes.Black,
66+
FontFamily = text.SelectedFontFamily,
67+
FontSize = text.SelectedFontSize,
68+
FontStyle = text.SelectedFontStyle,
69+
FontWeight = text.SelectedFontWeight
70+
};
71+
//paths.Add(GetPathFromGeometry(Brushes.Black, text.TextGeometry));
72+
}
73+
PathGeometry pathGeometry = geometry.GetFlattenedPathGeometry();
74+
75+
List<PathGeometry> pathGeometries = GeometryHelper.GenerateMultiplePaths(pathGeometry, graphic is DrawingModel);
76+
foreach (var geo in pathGeometries)
77+
{
78+
Path path = new Path
79+
{
80+
Data = geo,
81+
Stroke = Brushes.Black
82+
};
83+
paths.Add(path);
84+
}
85+
var example = new PathAnimationHelper(canvas, paths, graphic, hand);
86+
example.AnimatePathOnCanvas();
87+
88+
await example.tcs.Task;
89+
if (element != null)
90+
{
91+
canvas.Children.Add(element);
92+
Canvas.SetLeft(element, graphic.X);
93+
Canvas.SetTop(element, graphic.Y);
94+
int count = canvas.Children.Count - index - 1;
95+
canvas.Children.RemoveRange(index, count);
96+
index = canvas.Children.Count;
97+
}
98+
}
99+
}
100+
}
101+
canvas.Children.Remove(hand);
102+
await Task.Delay(500);
103+
if (isExport)
104+
exporter.StopCapture();
105+
}
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)