Пример #1
0
 def __init__(self, path, partitions=10, **kwargs):
     VMobject.__init__(self, **kwargs)
     rect = Rectangle(width=path.get_width() + self.margin,
                      height=path.get_height() + self.margin)
     rect.move_to(path)
     w = rect.get_width()
     h = rect.get_height()
     alpha = w / h
     hp = int(np.ceil(partitions / (2 * (alpha + 1))))
     wp = int(np.ceil(alpha * hp))
     sides = VGroup(*[
         Line(rect.get_corner(c1), rect.get_corner(c2))
         for c1, c2 in zip([UL, UR, DR, DL], [UR, DR, DL, UL])
     ])
     total_points = []
     for side, points in zip(sides, [wp, hp, wp, hp]):
         for p in range(points):
             total_points.append(side.point_from_proportion(p / points))
     total_points.append(total_points[0])
     middle = int(np.floor(len(total_points) / 2))
     draw_points = []
     for p in range(2, middle):
         draw_points.append(total_points[-p * self.sign])
         draw_points.append(total_points[p * self.sign])
     self.set_points_smoothly(draw_points)
Пример #2
0
    def __init__(self, mobject, midle_color=None, **kwargs):
        digest_config(self, kwargs)
        self.mobject = mobject
        self.rectangle_kwargs["color"] = self.color
        if midle_color == None:
            midle_color = self.rectangle_kwargs["color"]
        rectangle = Rectangle(height=mobject.get_height() + self.margin,
                              width=mobject.get_width() + self.margin,
                              **self.rectangle_kwargs)
        rectangle.move_to(mobject)
        rectangle.init_state = rectangle.copy()
        rectangle_width = rectangle.get_width()

        def return_updater(mob, alpha):
            dx = interpolate(-PI / 2, PI / 2, alpha)
            mob.become(mob.init_state)
            mob.set_width(rectangle_width * np.cos(dx), stretch=True)
            # dx should not be zero
            sign = -abs(dx) / (dx + 0.00000000001)
            direction = LEFT * sign
            reference_line = Line(
                rectangle.init_state.get_corner(UP + direction),
                rectangle.init_state.get_corner(DOWN + direction))
            mob.next_to(reference_line, -direction, buff=0)
            opacity = self.init_opacity + (self.max_opacity -
                                           self.init_opacity) * np.cos(dx)
            mob.set_style(fill_opacity=opacity)
            mob.set_color(
                interpolate_color(self.rectangle_kwargs["color"], midle_color,
                                  np.cos(dx)))

        super().__init__(rectangle, return_updater)
Пример #3
0
    def get_face_card_design(self, value, symbol):
        from for_3b1b_videos.pi_creature import PiCreature
        sub_rect = Rectangle(
            stroke_color=BLACK,
            fill_opacity=0,
            height=0.9 * self.get_height(),
            width=0.6 * self.get_width(),
        )
        sub_rect.move_to(self)

        # pi_color = average_color(symbol.get_color(), GREY)
        pi_color = symbol.get_color()
        pi_mode = {
            "J": "plain",
            "Q": "thinking",
            "K": "hooray"
        }[value]
        pi_creature = PiCreature(
            mode=pi_mode,
            color=pi_color,
        )
        pi_creature.set_width(0.8 * sub_rect.get_width())
        if value in ["Q", "K"]:
            prefix = "king" if value == "K" else "queen"
            crown = SVGMobject(file_name=prefix + "_crown")
            crown.set_stroke(width=0)
            crown.set_fill(YELLOW, 1)
            crown.stretch_to_fit_width(0.5 * sub_rect.get_width())
            crown.stretch_to_fit_height(0.17 * sub_rect.get_height())
            crown.move_to(pi_creature.eyes.get_center(), DOWN)
            pi_creature.add_to_back(crown)
            to_top_buff = 0
        else:
            to_top_buff = SMALL_BUFF * sub_rect.get_height()
        pi_creature.next_to(sub_rect.get_top(), DOWN, to_top_buff)
        # pi_creature.shift(0.05*sub_rect.get_width()*RIGHT)

        pi_copy = pi_creature.copy()
        pi_copy.rotate(np.pi, about_point=sub_rect.get_center())

        return VGroup(sub_rect, pi_creature, pi_copy)
Пример #4
0
    def get_face_card_design(self, value, symbol):
        from for_3b1b_videos.pi_creature import PiCreature
        sub_rect = Rectangle(
            stroke_color=BLACK,
            fill_opacity=0,
            height=0.9 * self.get_height(),
            width=0.6 * self.get_width(),
        )
        sub_rect.move_to(self)

        # pi_color = average_color(symbol.get_color(), GREY)
        pi_color = symbol.get_color()
        pi_mode = {
            "J": "plain",
            "Q": "thinking",
            "K": "hooray"
        }[value]
        pi_creature = PiCreature(
            mode=pi_mode,
            color=pi_color,
        )
        pi_creature.set_width(0.8 * sub_rect.get_width())
        if value in ["Q", "K"]:
            prefix = "king" if value == "K" else "queen"
            crown = SVGMobject(file_name=prefix + "_crown")
            crown.set_stroke(width=0)
            crown.set_fill(YELLOW, 1)
            crown.stretch_to_fit_width(0.5 * sub_rect.get_width())
            crown.stretch_to_fit_height(0.17 * sub_rect.get_height())
            crown.move_to(pi_creature.eyes.get_center(), DOWN)
            pi_creature.add_to_back(crown)
            to_top_buff = 0
        else:
            to_top_buff = SMALL_BUFF * sub_rect.get_height()
        pi_creature.next_to(sub_rect.get_top(), DOWN, to_top_buff)
        # pi_creature.shift(0.05*sub_rect.get_width()*RIGHT)

        pi_copy = pi_creature.copy()
        pi_copy.rotate(np.pi, about_point=sub_rect.get_center())

        return VGroup(sub_rect, pi_creature, pi_copy)
Пример #5
0
 def __init__(self, texmob, **kwargs):
     VMobject.__init__(self, **kwargs)
     rect = Rectangle(width=texmob.get_width() + self.margin,
                      height=texmob.get_height() + self.margin)
     rect.move_to(texmob)
     w = rect.get_width()
     h = rect.get_height()
     alpha = w / h
     hp = np.ceil(self.partitions / (2 * (alpha + 1)))
     wp = np.ceil(alpha * hp)
     sides = VGroup(*[
         Line(rect.get_corner(c1), rect.get_corner(c2))
         for c1, c2 in zip([UL, UR, DR, DL], [UR, DR, DL, UL])
     ])
     total_points = []
     for side, p in zip(sides, [wp, hp, wp, hp]):
         path = FreehandDraw(side, p).points
         for point in path:
             total_points.append(point)
     total_points.append(total_points[0])
     self.set_points_smoothly(total_points)
Пример #6
0
class Textbox(ControlMobject):
    CONFIG = {
        "value_type": np.dtype(object),
        "box_kwargs": {
            "width": 2.0,
            "height": 1.0,
            "fill_color": WHITE,
            "fill_opacity": 1.0,
        },
        "text_kwargs": {
            "color": BLUE
        },
        "text_buff": MED_SMALL_BUFF,
        "isInitiallyActive": False,
        "active_color": BLUE,
        "deactive_color": RED,
    }

    def __init__(self, value="", **kwargs):
        digest_config(self, kwargs)
        self.isActive = self.isInitiallyActive
        self.box = Rectangle(**self.box_kwargs)
        self.box.add_mouse_press_listner(self.box_on_mouse_press)
        self.text = Text(value, **self.text_kwargs)
        super().__init__(value, self.box, self.text, **kwargs)
        self.update_text(value)
        self.active_anim(self.isActive)
        self.add_key_press_listner(self.on_key_press)

    def set_value_anim(self, value):
        self.update_text(value)

    def update_text(self, value):
        text = self.text
        self.remove(text)
        text.__init__(value, **self.text_kwargs)
        height = text.get_height()
        text.set_width(self.box.get_width() - 2 * self.text_buff)
        if text.get_height() > height:
            text.set_height(height)
        text.add_updater(lambda mob: mob.move_to(self.box))
        text.fix_in_frame()
        self.add(text)

    def active_anim(self, isActive):
        if isActive:
            self.box.set_stroke(self.active_color)
        else:
            self.box.set_stroke(self.deactive_color)

    def box_on_mouse_press(self, mob, event_data):
        self.isActive = not self.isActive
        self.active_anim(self.isActive)
        return False

    def on_key_press(self, mob, event_data):
        symbol = event_data["symbol"]
        modifiers = event_data["modifiers"]
        char = chr(symbol)
        if mob.isActive:
            old_value = mob.get_value()
            new_value = old_value
            if char.isalnum():
                if (modifiers & PygletWindowKeys.MOD_SHIFT) or (
                        modifiers & PygletWindowKeys.MOD_CAPSLOCK):
                    new_value = old_value + char.upper()
                else:
                    new_value = old_value + char.lower()
            elif symbol in [PygletWindowKeys.SPACE]:
                new_value = old_value + char
            elif symbol == PygletWindowKeys.TAB:
                new_value = old_value + '\t'
            elif symbol == PygletWindowKeys.BACKSPACE:
                new_value = old_value[:-1] or ''
            mob.set_value(new_value)
            return False
Пример #7
0
class Checkbox(ControlMobject):
    CONFIG = {
        "value_type": np.dtype(bool),
        "rect_kwargs": {
            "width": 0.5,
            "height": 0.5,
            "fill_opacity": 0.0
        },
        "checkmark_kwargs": {
            "stroke_color": GREEN,
            "stroke_width": 6,
        },
        "cross_kwargs": {
            "stroke_color": RED,
            "stroke_width": 6,
        },
        "box_content_buff": SMALL_BUFF
    }

    def __init__(self, value=True, **kwargs):
        digest_config(self, kwargs)
        self.box = Rectangle(**self.rect_kwargs)
        self.box_content = self.get_checkmark() if value else self.get_cross()
        super().__init__(value, self.box, self.box_content, **kwargs)
        self.add_mouse_press_listner(self.on_mouse_press)

    def assert_value(self, value):
        assert (isinstance(value, bool))

    def toggle_value(self):
        super().set_value(not self.get_value())

    def set_value_anim(self, value):
        if value:
            self.box_content.become(self.get_checkmark())
        else:
            self.box_content.become(self.get_cross())

    def on_mouse_press(self, mob, event_data):
        mob.toggle_value()
        return False

    # Helper methods

    def get_checkmark(self):
        checkmark = VGroup(
            Line(UP / 2 + 2 * LEFT, DOWN + LEFT, **self.checkmark_kwargs),
            Line(DOWN + LEFT, UP + RIGHT, **self.checkmark_kwargs))

        checkmark.stretch_to_fit_width(self.box.get_width())
        checkmark.stretch_to_fit_height(self.box.get_height())
        checkmark.scale(0.5)
        checkmark.move_to(self.box)
        return checkmark

    def get_cross(self):
        cross = VGroup(Line(UP + LEFT, DOWN + RIGHT, **self.cross_kwargs),
                       Line(UP + RIGHT, DOWN + LEFT, **self.cross_kwargs))

        cross.stretch_to_fit_width(self.box.get_width())
        cross.stretch_to_fit_height(self.box.get_height())
        cross.scale(0.5)
        cross.move_to(self.box)
        return cross