mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Changed the defaults for where animations are written, and where images for ImageMobject and SVGMobject are sought after
This commit is contained in:
parent
0b595ed5f5
commit
ffcd9b5767
19 changed files with 68 additions and 147 deletions
|
@ -36,7 +36,7 @@ python extract_scene.py -p example_scenes.py SquareToCircle
|
|||
|
||||
`-p` gives a preview of an animation, `-w` will write it to a file, and `-s` will show/save the final image in the animation.
|
||||
|
||||
You will probably want to change the MOVIE_DIR constant to be whatever direction you want video files to output to.
|
||||
You will probably want to change the ANIMATIONS_DIR constant to be whatever direction you want video files to output to.
|
||||
|
||||
Look through the old_projects folder to see the code for previous 3b1b videos.
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class Camera(object):
|
|||
|
||||
def init_background(self):
|
||||
if self.background_image is not None:
|
||||
path = get_full_image_path(self.background_image)
|
||||
path = get_full_raster_image_path(self.background_image)
|
||||
image = Image.open(path).convert(self.image_mode)
|
||||
height, width = self.pixel_shape
|
||||
#TODO, how to gracefully handle backgrounds
|
||||
|
|
18
constants.py
18
constants.py
|
@ -61,19 +61,23 @@ RIGHT_SIDE = SPACE_WIDTH*RIGHT
|
|||
|
||||
# Change this to point to where you want
|
||||
# animation files to output
|
||||
MOVIE_DIR = os.path.join(os.path.expanduser('~'), "Dropbox (3Blue1Brown)/3Blue1Brown Team Folder/animations")
|
||||
STAGED_SCENES_DIR = os.path.join(MOVIE_DIR, "staged_scenes")
|
||||
MEDIA_DIR = os.path.join(os.path.expanduser('~'), "Dropbox (3Blue1Brown)/3Blue1Brown Team Folder")
|
||||
|
||||
ANIMATIONS_DIR = os.path.join(MEDIA_DIR, "animations")
|
||||
RASTER_IMAGE_DIR = os.path.join(MEDIA_DIR, "designs", "raster_images")
|
||||
SVG_IMAGE_DIR = os.path.join(MEDIA_DIR, "designs", "svg_images")
|
||||
#TODO, staged scenes should really go into a subdirectory of a given scenes directory
|
||||
STAGED_SCENES_DIR = os.path.join(ANIMATIONS_DIR, "staged_scenes")
|
||||
###
|
||||
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||
FILE_DIR = os.path.join(THIS_DIR, "files")
|
||||
IMAGE_DIR = os.path.join(FILE_DIR, "images")
|
||||
GIF_DIR = os.path.join(FILE_DIR, "gifs")
|
||||
TEX_DIR = os.path.join(FILE_DIR, "Tex")
|
||||
TEX_IMAGE_DIR = os.path.join(IMAGE_DIR, "Tex")
|
||||
TEX_IMAGE_DIR = TEX_DIR #TODO, What is this doing?
|
||||
#These two may be depricated now.
|
||||
MOBJECT_DIR = os.path.join(FILE_DIR, "mobjects")
|
||||
IMAGE_MOBJECT_DIR = os.path.join(MOBJECT_DIR, "image")
|
||||
|
||||
for folder in [FILE_DIR, IMAGE_DIR, GIF_DIR, MOVIE_DIR, TEX_DIR,
|
||||
for folder in [FILE_DIR, RASTER_IMAGE_DIR, SVG_IMAGE_DIR, ANIMATIONS_DIR, TEX_DIR,
|
||||
TEX_IMAGE_DIR, MOBJECT_DIR, IMAGE_MOBJECT_DIR,
|
||||
STAGED_SCENES_DIR]:
|
||||
if not os.path.exists(folder):
|
||||
|
@ -84,8 +88,6 @@ TEMPLATE_TEX_FILE = os.path.join(THIS_DIR, "template.tex")
|
|||
TEMPLATE_TEXT_FILE = os.path.join(THIS_DIR, "text_template.tex")
|
||||
|
||||
|
||||
LOGO_PATH = os.path.join(IMAGE_DIR, "logo.png")
|
||||
|
||||
FFMPEG_BIN = "ffmpeg"
|
||||
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ def main():
|
|||
)
|
||||
|
||||
config["output_directory"] = os.path.join(
|
||||
MOVIE_DIR,
|
||||
ANIMATIONS_DIR,
|
||||
config["file"].replace(".py", "")
|
||||
)
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 480 480" style="enable-background:new 0 0 480 480;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
|
||||
.st1{fill:none;stroke:#000000;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<path class="st1" d="M220.1,222.2l-93.9,73.6l127.4-70.5c3.4,0.1,6.8,0.2,10.2,0.2c90.3,0,163.5-40.5,163.5-90.4
|
||||
s-73.2-90.4-163.5-90.4S100.3,85.1,100.3,135C100.3,176.6,151,211.6,220.1,222.2L220.1,222.2z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 716 B |
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 480 480" style="enable-background:new 0 0 480 480;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;}
|
||||
.st1{fill:none;stroke:#000000;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<circle class="st1" cx="143.8" cy="268" r="22.6"/>
|
||||
<circle class="st1" cx="111.8" cy="313.2" r="13.2"/>
|
||||
<circle class="st1" cx="80.7" cy="334.2" r="7"/>
|
||||
<path class="st1" d="M293.8,49.9c3-1,6.4-1.9,9.7-1.9c16.8,0,30.4,13.6,30.4,30.4c0,1.9-0.2,3.7-0.5,5.5l0,0
|
||||
c10.8,4.5,21,16.2,20.5,28.6c-0.4,9.1-1.2,18.8-11.3,27.7l0,0c8.5,6.8,8.7,29.6,4.7,39c-4.1,9.7-11.8,19.6-33.4,27.2
|
||||
c-8.2,19.4-30.1,35.7-52.4,35.7c-9.6,0-18.9-2.5-26.7-6.9l0,0c-8.1,5.6-17.7,8.8-28.3,8.8c-18.9,0-35.8-10.6-44.4-26l0,0
|
||||
c-22.5,0-45.3-15.3-49.5-36.6l0,0c-19.2-5.7-33.1-23.4-33.1-44.5c0-9.7,2.9-18.7,8-26.2l0,0c-2.7-5.5-4.2-11.8-4.2-18.3
|
||||
c0-21.9,17.3-40,38.8-41.6l0,0c7.3-14.6,22.4-24.7,39.9-24.7c4.8,0,9.3,0.7,13.6,2.1l0,0c7.6-8.3,18.7-13.5,30.9-13.5
|
||||
c12.8,0,24.2,5.7,31.9,14.8l0,0c6-4.7,13.6-7.6,21.7-7.6C277,22.1,290.5,33.9,293.8,49.9L293.8,49.9z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.3 KiB |
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 480 480" style="enable-background:new 0 0 480 480;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#0C7F99;}
|
||||
</style>
|
||||
<path class="st0" d="M251.6,114.7c0,4.2-1.4,8.2-3.7,11.3l-30.4,0.3c-2.6-3.1-4-7.3-4-11.6c0-10.5,8.5-19,19-19
|
||||
C243.1,95.6,251.6,104.2,251.6,114.7z"/>
|
||||
<path class="st0" d="M306.6,114.7c0,4.2-1.4,8.2-3.7,11.3l-30.4,0.3c-2.6-3.1-4-7.3-4-11.6c0-10.5,8.5-19,19-19
|
||||
C298.1,95.6,306.6,104.2,306.6,114.7z"/>
|
||||
<path d="M238,99.8c-1.3,0.1-2.3,1.1-2.3,2.4c0,1.3,1.1,2.4,2.4,2.4c1.3,0,2.4-1.1,2.4-2.4c0-1.3-1.1-2.4-2.4-2.4
|
||||
C238.1,99.8,238,99.8,238,99.8l2.9-1c4.3,0,7.7,3.5,7.7,7.7s-3.5,7.7-7.7,7.7s-7.7-3.5-7.7-7.7s3.5-7.7,7.7-7.7"/>
|
||||
<path d="M293,99.8c-1.3,0.1-2.3,1.1-2.3,2.4c0,1.3,1.1,2.4,2.4,2.4s2.4-1.1,2.4-2.4c0-1.3-1.1-2.4-2.4-2.4
|
||||
C293.1,99.8,293,99.8,293,99.8l2.9-1c4.3,0,7.7,3.5,7.7,7.7s-3.5,7.7-7.7,7.7s-7.7-3.5-7.7-7.7s3.5-7.7,7.7-7.7"/>
|
||||
<path class="st1" d="M228.4,157.1h64.4c-15.4,63.8-25.1,105.4-25.1,151c0,8,0,69.5,23.4,69.5c12,0,22.2-10.8,22.2-20.5
|
||||
c0-2.8,0-4-4-12.5c-15.4-39.3-15.4-88.3-15.4-92.3c0-3.4,0-43.9,12-95.1h63.8c7.4,0,26.2,0,26.2-18.2c0-12.5-10.8-12.5-21.1-12.5
|
||||
H187.4c-13.1,0-32.5,0-58.7,27.9c-14.8,16.5-33,46.7-33,50.1s2.8,4.6,6.3,4.6c4,0,4.6-1.7,7.4-5.1c29.6-46.7,59.2-46.7,73.5-46.7
|
||||
h32.5c-12.5,42.7-26.8,92.3-73.5,192c-4.6,9.1-4.6,10.3-4.6,13.7c0,12,10.3,14.8,15.4,14.8c16.5,0,21.1-14.8,27.9-38.7
|
||||
c9.1-29.1,9.1-30.2,14.8-53L228.4,157.1"/>
|
||||
<path d="M246.3,149.1c5.5,0,1.9,0.1,13.5,0c10.3-0.1,12.4-0.1,15.7-0.2c0,0-0.3-3.1-0.3-3.1c-3.7,0.1-9.3,0.2-14.7,0.2
|
||||
c-3.9,0-8.5,0-14.6,0"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.8 KiB |
10
helpers.py
10
helpers.py
|
@ -410,13 +410,13 @@ def cammel_case_initials(name):
|
|||
|
||||
################################################
|
||||
|
||||
def get_full_image_path(image_file_name):
|
||||
def get_full_raster_image_path(image_file_name):
|
||||
possible_paths = [
|
||||
image_file_name,
|
||||
os.path.join(IMAGE_DIR, image_file_name),
|
||||
os.path.join(IMAGE_DIR, image_file_name + ".jpg"),
|
||||
os.path.join(IMAGE_DIR, image_file_name + ".png"),
|
||||
os.path.join(IMAGE_DIR, image_file_name + ".gif"),
|
||||
os.path.join(RASTER_IMAGE_DIR, image_file_name),
|
||||
os.path.join(RASTER_IMAGE_DIR, image_file_name + ".jpg"),
|
||||
os.path.join(RASTER_IMAGE_DIR, image_file_name + ".png"),
|
||||
os.path.join(RASTER_IMAGE_DIR, image_file_name + ".gif"),
|
||||
]
|
||||
for path in possible_paths:
|
||||
if os.path.exists(path):
|
||||
|
|
|
@ -23,7 +23,7 @@ class ImageMobject(Mobject):
|
|||
def __init__(self, filename_or_array, **kwargs):
|
||||
digest_config(self, kwargs)
|
||||
if isinstance(filename_or_array, str):
|
||||
path = get_full_image_path(filename_or_array)
|
||||
path = get_full_raster_image_path(filename_or_array)
|
||||
image = Image.open(path).convert(self.image_mode)
|
||||
self.pixel_array = np.array(image)
|
||||
else:
|
||||
|
|
|
@ -96,7 +96,7 @@ class Mobject(object):
|
|||
|
||||
def save_image(self, name = None):
|
||||
self.get_image().save(
|
||||
os.path.join(MOVIE_DIR, (name or str(self)) + ".png")
|
||||
os.path.join(ANIMATIONS_DIR, (name or str(self)) + ".png")
|
||||
)
|
||||
|
||||
def copy(self):
|
||||
|
|
|
@ -37,8 +37,8 @@ class SVGMobject(VMobject):
|
|||
raise Exception("Must specify file for SVGMobject")
|
||||
possible_paths = [
|
||||
self.file_name,
|
||||
os.path.join(IMAGE_DIR, self.file_name),
|
||||
os.path.join(IMAGE_DIR, self.file_name + ".svg"),
|
||||
os.path.join(SVG_IMAGE_DIR, self.file_name),
|
||||
os.path.join(SVG_IMAGE_DIR, self.file_name + ".svg"),
|
||||
]
|
||||
for path in possible_paths:
|
||||
if os.path.exists(path):
|
||||
|
|
|
@ -1532,7 +1532,7 @@ class BreakUpMacroPatterns(IntroduceEachLayer):
|
|||
prefixes = self.prefixes
|
||||
vects = [
|
||||
np.array(Image.open(
|
||||
get_full_image_path("handwritten_" + p),
|
||||
get_full_raster_image_path("handwritten_" + p),
|
||||
))[:,:,0].flatten()/255.0
|
||||
for p in prefixes
|
||||
]
|
||||
|
@ -1921,7 +1921,7 @@ class SecondLayerIsLittleEdgeLayer(IntroduceEachLayer):
|
|||
def setup_activations_and_nines(self):
|
||||
layers = self.network_mob.layers
|
||||
nine_im, loop_im, line_im = images = [
|
||||
Image.open(get_full_image_path("handwritten_%s"%s))
|
||||
Image.open(get_full_raster_image_path("handwritten_%s"%s))
|
||||
for s in "nine", "upper_loop", "right_line"
|
||||
]
|
||||
nine_array, loop_array, line_array = [
|
||||
|
|
|
@ -14,7 +14,7 @@ from scene import Scene, SceneFromVideo
|
|||
from script_wrapper import command_line_create_scene
|
||||
|
||||
MOVIE_PREFIX = "counting_in_binary/"
|
||||
BASE_HAND_FILE = os.path.join(MOVIE_DIR, MOVIE_PREFIX, "Base.mp4")
|
||||
BASE_HAND_FILE = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, "Base.mp4")
|
||||
FORCED_FRAME_DURATION = 0.02
|
||||
TIME_RANGE = (0, 42)
|
||||
INITIAL_PADDING = 27
|
||||
|
@ -88,7 +88,7 @@ class Hand(ImageMobject):
|
|||
def __init__(self, num, small = False, **kwargs):
|
||||
Mobject2D.__init__(self, **kwargs)
|
||||
path = os.path.join(
|
||||
MOVIE_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
|
||||
ANIMATIONS_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
|
||||
)
|
||||
invert = False
|
||||
if not self.read_in_cached_attrs(path, invert):
|
||||
|
@ -164,7 +164,7 @@ class SaveEachNumber(OverHand):
|
|||
OverHand.construct(self)
|
||||
for count in COUNT_TO_FRAME_NUM:
|
||||
path = os.path.join(
|
||||
MOVIE_DIR, MOVIE_PREFIX, "images",
|
||||
ANIMATIONS_DIR, MOVIE_PREFIX, "images",
|
||||
"Hand%d.png"%count
|
||||
)
|
||||
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
|
||||
|
|
|
@ -55,7 +55,7 @@ class Hand(ImageMobject):
|
|||
def __init__(self, num, **kwargs):
|
||||
Mobject2D.__init__(self, **kwargs)
|
||||
path = os.path.join(
|
||||
MOVIE_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
|
||||
ANIMATIONS_DIR, MOVIE_PREFIX, "images", "Hand%d.png"%num
|
||||
)
|
||||
invert = False
|
||||
if self.read_in_cached_attrs(path, invert):
|
||||
|
@ -81,14 +81,14 @@ class EdgeDetection(SceneFromVideo):
|
|||
return "-".join([filename.split(".")[0], str(t1), str(t2)])
|
||||
|
||||
def construct(self, filename, t1, t2):
|
||||
path = os.path.join(MOVIE_DIR, filename)
|
||||
path = os.path.join(ANIMATIONS_DIR, filename)
|
||||
SceneFromVideo.construct(self, path)
|
||||
self.apply_gaussian_blur()
|
||||
self.apply_edge_detection(t1, t2)
|
||||
|
||||
class BufferedCounting(SceneFromVideo):
|
||||
def construct(self):
|
||||
path = os.path.join(MOVIE_DIR, "CountingInBinary.m4v")
|
||||
path = os.path.join(ANIMATIONS_DIR, "CountingInBinary.m4v")
|
||||
time_range = (3, 42)
|
||||
SceneFromVideo.construct(self, path, time_range = time_range)
|
||||
self.buffer_pixels(spreads = (3, 2))
|
||||
|
@ -128,7 +128,7 @@ class ClearLeftSide(SceneFromVideo):
|
|||
return scenename
|
||||
|
||||
def construct(self, scenename):
|
||||
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, scenename + ".mp4")
|
||||
path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, scenename + ".mp4")
|
||||
SceneFromVideo.construct(self, path)
|
||||
self.highlight_region_over_time_range(
|
||||
Region(lambda x, y : x < -1, shape = self.shape)
|
||||
|
@ -146,7 +146,7 @@ class DraggedPixels(SceneFromVideo):
|
|||
return args[0]
|
||||
|
||||
def construct(self, video):
|
||||
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, video+".mp4")
|
||||
path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, video+".mp4")
|
||||
SceneFromVideo.construct(self, path)
|
||||
self.drag_pixels()
|
||||
|
||||
|
@ -163,11 +163,11 @@ class DraggedPixels(SceneFromVideo):
|
|||
|
||||
class SaveEachNumber(SceneFromVideo):
|
||||
def construct(self):
|
||||
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, "ClearLeftSideBufferedCounting.mp4")
|
||||
path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, "ClearLeftSideBufferedCounting.mp4")
|
||||
SceneFromVideo.construct(self, path)
|
||||
for count in COUNT_TO_FRAME_NUM:
|
||||
path = os.path.join(
|
||||
MOVIE_DIR, MOVIE_PREFIX, "images",
|
||||
ANIMATIONS_DIR, MOVIE_PREFIX, "images",
|
||||
"Hand%d.png"%count
|
||||
)
|
||||
Image.fromarray(self.frames[COUNT_TO_FRAME_NUM[count]]).save(path)
|
||||
|
@ -182,7 +182,7 @@ class ShowCounting(SceneFromVideo):
|
|||
return filename
|
||||
|
||||
def construct(self, filename):
|
||||
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, filename + ".mp4")
|
||||
path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, filename + ".mp4")
|
||||
SceneFromVideo.construct(self, path)
|
||||
total_time = len(self.frames)*self.frame_duration
|
||||
for count in range(32):
|
||||
|
@ -207,7 +207,7 @@ class ShowFrameNum(SceneFromVideo):
|
|||
return filename
|
||||
|
||||
def construct(self, filename):
|
||||
path = os.path.join(MOVIE_DIR, MOVIE_PREFIX, filename+".mp4")
|
||||
path = os.path.join(ANIMATIONS_DIR, MOVIE_PREFIX, filename+".mp4")
|
||||
SceneFromVideo.construct(self, path)
|
||||
for frame, count in zip(self.frames, it.count()):
|
||||
print(count + "of" + len(self.frames))
|
||||
|
|
|
@ -32,7 +32,7 @@ class Scene(object):
|
|||
"save_frames" : False,
|
||||
"save_pngs" : False,
|
||||
"pngs_mode" : "RGBA",
|
||||
"output_directory" : MOVIE_DIR,
|
||||
"output_directory" : ANIMATIONS_DIR,
|
||||
"name" : None,
|
||||
"always_continually_update" : False,
|
||||
"random_seed" : 0,
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
import sys
|
||||
import inspect
|
||||
import os
|
||||
import shutil
|
||||
import itertools as it
|
||||
from extract_scene import is_scene, get_module
|
||||
from constants import MOVIE_DIR, STAGED_SCENES_DIR
|
||||
|
||||
|
||||
def get_sorted_scene_names(module_name):
|
||||
module = get_module(module_name)
|
||||
line_to_scene = {}
|
||||
for name, scene_class in inspect.getmembers(module, is_scene):
|
||||
lines, line_no = inspect.getsourcelines(scene_class)
|
||||
line_to_scene[line_no] = name
|
||||
return [
|
||||
line_to_scene[line_no]
|
||||
for line_no in sorted(line_to_scene.keys())
|
||||
]
|
||||
|
||||
|
||||
|
||||
def stage_animaions(module_name):
|
||||
scene_names = get_sorted_scene_names(module_name)
|
||||
movie_dir = os.path.join(
|
||||
MOVIE_DIR, module_name.replace(".py", "")
|
||||
)
|
||||
files = os.listdir(movie_dir)
|
||||
sorted_files = []
|
||||
for scene in scene_names:
|
||||
for clip in filter(lambda f : f.startswith(scene), files):
|
||||
sorted_files.append(
|
||||
os.path.join(movie_dir, clip)
|
||||
)
|
||||
for f in os.listdir(STAGED_SCENES_DIR):
|
||||
os.remove(os.path.join(STAGED_SCENES_DIR, f))
|
||||
for f, count in zip(sorted_files, it.count()):
|
||||
symlink_name = os.path.join(
|
||||
STAGED_SCENES_DIR,
|
||||
"Scene_%03d"%count + f.split(os.sep)[-1]
|
||||
)
|
||||
os.symlink(f, symlink_name)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
raise Exception("No module given.")
|
||||
module_name = sys.argv[1]
|
||||
stage_animaions(module_name)
|
|
@ -4,7 +4,7 @@ import os
|
|||
import shutil
|
||||
import itertools as it
|
||||
from extract_scene import is_scene, get_module
|
||||
from constants import MOVIE_DIR, STAGED_SCENES_DIR
|
||||
from constants import ANIMATIONS_DIR, STAGED_SCENES_DIR
|
||||
|
||||
|
||||
def get_sorted_scene_names(module_name):
|
||||
|
@ -22,15 +22,15 @@ def get_sorted_scene_names(module_name):
|
|||
|
||||
def stage_animaions(module_name):
|
||||
scene_names = get_sorted_scene_names(module_name)
|
||||
movie_dir = os.path.join(
|
||||
MOVIE_DIR, module_name.replace(".py", "")
|
||||
animation_dir = os.path.join(
|
||||
ANIMATIONS_DIR, module_name.replace(".py", "")
|
||||
)
|
||||
files = os.listdir(movie_dir)
|
||||
files = os.listdir(animation_dir)
|
||||
sorted_files = []
|
||||
for scene in scene_names:
|
||||
for clip in filter(lambda f : f.startswith(scene), files):
|
||||
sorted_files.append(
|
||||
os.path.join(movie_dir, clip)
|
||||
os.path.join(animation_dir, clip)
|
||||
)
|
||||
for f in os.listdir(STAGED_SCENES_DIR):
|
||||
os.remove(os.path.join(STAGED_SCENES_DIR, f))
|
||||
|
|
|
@ -13,7 +13,7 @@ from animation.simple_animations import Write, ShowCreation, AnimationGroup
|
|||
from scene import Scene
|
||||
|
||||
|
||||
PI_CREATURE_DIR = os.path.join(IMAGE_DIR, "PiCreature")
|
||||
PI_CREATURE_DIR = os.path.join(MEDIA_DIR, "designs", "PiCreature")
|
||||
PI_CREATURE_SCALE_FACTOR = 0.5
|
||||
|
||||
LEFT_EYE_INDEX = 0
|
||||
|
@ -51,7 +51,7 @@ class PiCreature(SVGMobject):
|
|||
except:
|
||||
warnings.warn("No PiCreature design with mode %s"%mode)
|
||||
svg_file = os.path.join(
|
||||
PI_CREATURE_DIR,
|
||||
FILE_DIR,
|
||||
"PiCreatures_plain.svg"
|
||||
)
|
||||
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
|
||||
|
|
|
@ -388,6 +388,10 @@ class Bubble(SVGMobject):
|
|||
digest_config(self, kwargs, locals())
|
||||
if self.file_name is None:
|
||||
raise Exception("Must invoke Bubble subclass")
|
||||
try:
|
||||
SVGMobject.__init__(self, **kwargs)
|
||||
except IOError as err:
|
||||
self.file_name = os.path.join(FILE_DIR, self.file_name)
|
||||
SVGMobject.__init__(self, **kwargs)
|
||||
self.center()
|
||||
self.stretch_to_fit_height(self.height)
|
||||
|
@ -515,4 +519,22 @@ class Broadcast(LaggedStart):
|
|||
self, ApplyMethod, circles,
|
||||
lambda c : (c.restore,),
|
||||
**kwargs
|
||||
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue