Last active
August 20, 2024 11:04
-
-
Save kjlubick/f50f3b1de8ced24c7b27bb48e15834f8 to your computer and use it in GitHub Desktop.
Example Manim code for producing videos like https://www.youtube.com/watch?list=PLDs5gxU1J5CLKlTjZKLtPau7DFrAnDRHD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from manim import * | |
LM_MONO = "Latin Modern Mono" | |
if sys.platform == "win32": | |
# Windows names this font differently for unknown reasons | |
LM_MONO = "LM Mono 10" | |
ROBOTO_MONO = "Roboto Mono" | |
RED_60 = "#da1e28" | |
PC_COLOR = RED_60 | |
class AnimatedCodeExecution(MovingCameraScene): | |
# It is not recommended to override the __init__ method in user Scenes. | |
# For code that should be ran before a Scene is rendered, use Scene.setup() instead | |
def setup(self): | |
# Setting fields to None, just to make them explicit | |
self.pc = None | |
self.pc_loc = (-1, 0, 0) | |
def init_code(self, source, upper_left=[-7.3, 3.5, 0], | |
scale=0.9): | |
code = CodeWithPalette( | |
code=source, | |
# must be set or indentation of any kind will | |
# be the default (3) | |
tab_width=4, | |
line_spacing=0.6, | |
background_stroke_width=1, | |
background_stroke_color=GREY, | |
insert_line_no=True, | |
style="xcode", | |
background="rectangle", | |
language="python", | |
font=ROBOTO_MONO, | |
name="source_code" | |
) | |
# Hide outline | |
code[0].set_opacity(0) | |
# Line numbers with 1 in the low digit are a bit | |
# wonky, alignment wise. | |
code[1][0].shift(LEFT * 0.04) | |
if len(code[1]) > 10: | |
code[1][10].shift(LEFT * 0.04) | |
if len(code[1]) > 20: | |
code[1][20].shift(LEFT * 0.04) | |
# Font size is not the best way to scale code things - it seems | |
# rather discrete sometimes. | |
code.scale(scale) | |
code.align_to(upper_left, UL) | |
self.code = code | |
return code | |
def move_pc(self, line, start, end, target=None): | |
self.pc_loc = (line, start, end) | |
if not target: | |
target = self.code[2][line - 1][start:end] | |
if not self.pc: | |
self.pc = SurroundingRectangle(target, | |
buff=0.07, color=PC_COLOR, corner_radius=0.1) | |
return Create(self.pc) | |
self.bring_to_front(self.pc) | |
new_pc = SurroundingRectangle(target, | |
buff=0.07, color=PC_COLOR, corner_radius=0.1) | |
return Transform(self.pc, new_pc) | |
class CodeWithPalette(Code): | |
def _gen_code_json(self): | |
super()._gen_code_json() | |
palette_swap = { | |
# purple used by if and for is just a little too light | |
# for me | |
'#A90D91': '#900A7F', | |
} | |
# print(self.code_json) | |
for line in self.code_json: | |
for entry in line: | |
entry[1] = palette_swap.get(entry[1], entry[1]) | |
quine = """ | |
class ExampleScene(AnimatedCodeExecution): | |
def construct(self): | |
self.camera.background_color = WHITE | |
code = self.init_code(quine) | |
self.add(code) | |
self.pause() | |
self.play(self.move_pc(1, 6, 18)) | |
self.pause() | |
self.play(self.move_pc(2, 1, 4)) | |
self.pause() | |
""" | |
# Render this with | |
# manim render -qm sample_code.py ExampleScene | |
class ExampleScene(AnimatedCodeExecution): | |
def construct(self): | |
self.camera.background_color = WHITE | |
code = self.init_code(quine) | |
self.add(code) | |
# The index_labels function is very handy for identifying | |
# which indexes the mobjects you care about correspond to. | |
# self.add(index_labels(code)) | |
self.pause() | |
# Highlight ExampleScene. Note that spaces are turned into | |
# mobjects, so you must count them. | |
self.play(self.move_pc(1, 6, 18)) | |
self.pause() | |
# However tabs are grouped together into "one" space, that | |
# you should probably skip. (This highlights the def) | |
self.play(self.move_pc(2, 1, 4)) | |
self.pause() | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Copyright 2023 Kaylee Lubick | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is what it renders to
https://user-images.githubusercontent.com/6819944/210455511-416dca9a-ab2e-41fe-aad1-54fca31a1599.mp4