private static AssLine CreatePostAnimationClusterLine(AssLine originalLine, AssLine lastLine, DateTime start, DateTime end, List<AnimationWithSectionIndex> animsWithSection) { AssLine newLine = (AssLine)lastLine.Clone(); newLine.Start = start; newLine.End = end; foreach (AnimationWithSectionIndex animWithSection in animsWithSection.OrderBy(a => a.Animation.EndTime)) { if (animWithSection.Animation.AffectsText) ResetText(newLine, originalLine); ApplyAnimation(newLine, animWithSection, 1); } return newLine; }
private static AssLine CreateInitialLine(AssLine originalLine, List <AnimationWithSectionIndex> anims) { AssLine newLine = (AssLine)originalLine.Clone(); foreach (AnimationWithSectionIndex anim in anims.Where(a => a.Animation.EndTime < originalLine.Start) .OrderBy(a => a.Animation.EndTime)) { ApplyAnimation(newLine, anim, 1); } foreach (AnimationWithSectionIndex anim in anims.Where(a => a.Animation.AffectsPast && a.Animation.StartTime >= originalLine.Start) .OrderByDescending(a => a.Animation.StartTime)) { ApplyAnimation(newLine, anim, 0); } return(newLine); }
private static IEnumerable <AssLine> CreateFrameLines(AssDocument document, AssLine originalLine, TimeRange timeRange, List <AnimationWithSectionIndex> animations) { int rangeStartFrame = TimeUtil.StartTimeToFrame(timeRange.Start); int rangeEndFrame = TimeUtil.EndTimeToFrame(timeRange.End); const int frameStepSize = 2; int subStepFrames = (rangeEndFrame + 1 - rangeStartFrame) % frameStepSize; int lastIterationFrame = rangeEndFrame + 1 - subStepFrames - frameStepSize; bool needTextReset = animations.Any(a => a.Animation.AffectsText); AssLine frameLine = originalLine; for (int frame = rangeStartFrame; frame <= lastIterationFrame; frame += frameStepSize) { frameLine = (AssLine)frameLine.Clone(); frameLine.Start = TimeUtil.FrameToStartTime(frame); frameLine.End = frame < lastIterationFrame?TimeUtil.FrameToEndTime(frame + frameStepSize - 1) : timeRange.End; frameLine.Position = originalLine.Position ?? document.GetDefaultPosition(originalLine.AnchorPoint); if (needTextReset) { ResetText(frameLine, originalLine); } float interpFrame = frame + (frameStepSize - 1) / 2.0f; foreach (AnimationWithSectionIndex animWithSection in animations) { int animStartFrame = TimeUtil.StartTimeToFrame(animWithSection.Animation.StartTime); int animEndFrame = TimeUtil.EndTimeToFrame(animWithSection.Animation.EndTime); if (interpFrame >= animStartFrame && interpFrame < animEndFrame) { float t = (interpFrame - animStartFrame) / (animEndFrame - animStartFrame); ApplyAnimation(frameLine, animWithSection, t); } else if (interpFrame >= animEndFrame && interpFrame < animEndFrame + frameStepSize) { ApplyAnimation(frameLine, animWithSection, 1); } } yield return(frameLine); } }
private static IEnumerable <AssLine> CreateFrameLines(AssLine originalLine, TimeRange timeRange, List <AnimationWithSectionIndex> animations) { int rangeStartFrame = TimeUtil.TimeToFrame(timeRange.Start); int rangeEndFrame = TimeUtil.TimeToFrame(timeRange.End); const int frameStepSize = 2; int lastIterationFrame = rangeStartFrame + (rangeEndFrame - 1 - rangeStartFrame) / frameStepSize * frameStepSize; bool needTextReset = animations.Any(a => a.Animation.AffectsText); AssLine frameLine = originalLine; for (int frame = rangeStartFrame; frame <= lastIterationFrame; frame += frameStepSize) { frameLine = (AssLine)frameLine.Clone(); frameLine.Start = TimeUtil.FrameToTime(frame); frameLine.End = frame < lastIterationFrame?TimeUtil.FrameToTime(frame + frameStepSize) : timeRange.End; if (needTextReset) { ResetText(frameLine, originalLine); } int interpFrame = frame + frameStepSize / 2; foreach (AnimationWithSectionIndex animWithSection in animations) { int animStartFrame = TimeUtil.TimeToFrame(animWithSection.Animation.StartTime); int animEndFrame = TimeUtil.TimeToFrame(animWithSection.Animation.EndTime); if (interpFrame >= animStartFrame && interpFrame < animEndFrame) { float t = (float)(interpFrame - animStartFrame) / (animEndFrame - animStartFrame); ApplyAnimation(frameLine, animWithSection, t); } else if (interpFrame >= animEndFrame && interpFrame < animEndFrame + frameStepSize) { ApplyAnimation(frameLine, animWithSection, 1); } } yield return(frameLine); } }
private static IEnumerable <AssLine> CreateChromaLines(AssLine originalLine, List <Color> colors, PointF center, int maxOffsetX, int maxOffsetY, int durationMs, bool moveIn) { if (originalLine.Sections.Count == 0) { yield break; } for (int i = 0; i < colors.Count; i++) { if (colors[i].A == 0) { continue; } AssLine chromaLine = (AssLine)originalLine.Clone(); foreach (Section section in chromaLine.Sections) { int alpha = (int)(section.ForeColor.A * (colors[i].A / 255.0f)); section.ForeColor = Color.FromArgb(alpha, colors[i].R, colors[i].G, colors[i].B); section.BackColor = Color.Empty; section.ShadowColors.Clear(); } float offsetFactor = colors.Count > 1 ? (float)i / (colors.Count - 1) : 0.5f; float offsetX = offsetFactor * (-maxOffsetX * 2) + maxOffsetX; float offsetY = offsetFactor * (-maxOffsetY * 2) + maxOffsetY; PointF farPosition = new PointF(center.X + offsetX, center.Y + offsetY); PointF nearPosition = new PointF(center.X + offsetX / 5, center.Y + offsetY / 5); if (moveIn) { chromaLine.End = TimeUtil.RoundTimeToFrameCenter(originalLine.Start.AddMilliseconds(durationMs)); chromaLine.Animations.Add(new MoveAnimation(chromaLine.Start, farPosition, chromaLine.End, nearPosition)); } else { chromaLine.Start = TimeUtil.RoundTimeToFrameCenter(originalLine.End.AddMilliseconds(-durationMs)); chromaLine.Animations.Add(new MoveAnimation(chromaLine.Start, nearPosition, chromaLine.End, farPosition)); } yield return(chromaLine); } }