Skip to content

Instantly share code, notes, and snippets.

@kjlubick
Created January 3, 2023 22:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kjlubick/f50f3b1de8ced24c7b27bb48e15834f8 to your computer and use it in GitHub Desktop.
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
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()
Copyright 2023 Kevin 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.
@kjlubick
Copy link
Author

kjlubick commented Jan 3, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment