File size: 5,789 Bytes
8e64a96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
from PIL import Image, ImageDraw, ImageFont

config = {
    "ids": ["falling_plain"],
    "name": "Falling Plain",
    "panels": ["color", "font", "size", "position"],
    "default_font": "vazir"
}

frontend_template = ""

def draw_frame(draw, img, width, height, style_config, lines, line_metrics, active_idx, font, color_parser, word_infos=None):
    is_rtl = getattr(style_config, 'text_direction', 'rtl') != 'ltr'
    # رنگ متن پایه (خاموش)
    custom_text = style_config.styleColors.get('falling_plain', '#FFFFFF')
    base_text_color = color_parser(custom_text, (255, 255, 255, 255))
    
    # رنگ کلمه فعال (روشن)
    active_hex = style_config.styleActiveColors.get('falling_plain', '#FFEB3B')
    active_text_color = color_parser(active_hex, (255, 235, 59, 255))

    line_height_px = int(style_config.fontSize * 1.5)
    total_block_height = len(lines) * line_height_px
    bottom_reference = height - style_config.marginV
    start_y_of_block = bottom_reference - total_block_height
    
    space_w = draw.textlength(" ", font=font)
    
    try:
        ref_bbox = draw.textbbox((0, 0), "سلام", font=font, direction=getattr(style_config, 'text_direction', 'rtl'), language=getattr(style_config, 'lang_code', 'fa'))
        standard_text_visual_center_y = (ref_bbox[1] + ref_bbox[3]) / 2.0
        standard_text_offset_y = ref_bbox[1]
        standard_text_h = ref_bbox[3] - ref_bbox[1]
    except:
        standard_text_visual_center_y = style_config.fontSize / 2.0
        standard_text_offset_y = 0
        standard_text_h = style_config.fontSize

    words_to_draw = []
    global_word_counter = 0
    temp_y = start_y_of_block

    # محاسبه موقعیت هندسی تک‌تک کلمات در تصویر
    for line_idx, metrics in enumerate(line_metrics):
        line_start_idx = sum(len(m["words"]) for m in line_metrics[:line_idx])
        cursor_x = (width + metrics["width"]) / 2 + (style_config.x or 0) if is_rtl else (width - metrics["width"]) / 2 + (style_config.x or 0)
        line_center_y = temp_y + (line_height_px / 2.0)
        
        for w_i, word in enumerate(metrics["words"]):
            g_idx = line_start_idx + w_i
            w_len = metrics["word_widths"][w_i]
            text_y_pos = line_center_y - standard_text_visual_center_y
            word_x = (cursor_x - w_len) if is_rtl else cursor_x
            
            words_to_draw.append({
                "text": word, "x": word_x, "y": text_y_pos, "width": w_len, 
                "global_idx": global_word_counter
            })
            
            cursor_x += (-(w_len + space_w) if is_rtl else (w_len + space_w))
            global_word_counter += 1
        temp_y += line_height_px

    VERTICAL_CORRECTION = int(style_config.fontSize * 0.1)
    current_render_time = getattr(style_config, 'current_render_time', 0.0)

    # رسم کلمات با انیمیشن فرود از ارتفاع -45px
    for item in words_to_draw:
        should_draw = False
        y_offset = 0
        alpha_factor = 1.0
        is_active = False

        if word_infos and item["global_idx"] < len(word_infos):
            w_info = word_infos[item["global_idx"]]
            if current_render_time >= w_info.start:
                should_draw = True
                is_active = current_render_time < w_info.end
                
                # اعمال انیمیشن سقوط برای کلمه فعال
                if is_active:
                    time_passed = current_render_time - w_info.start
                    anim_dur = 0.25
                    if time_passed < anim_dur:
                        progress = time_passed / anim_dur
                        ease = 1 - (1 - progress) * (1 - progress)
                        y_offset = -45 * (1 - ease)
                        alpha_factor = ease
                    else:
                        y_offset = 0
                        alpha_factor = 1.0
                else:
                    y_offset = 0
                    alpha_factor = 1.0
            else:
                # کلمات جلو (آینده) به هیچ عنوان ترسیم نمی‌شوند
                should_draw = False
        elif active_idx != -1: 
            if item["global_idx"] <= active_idx:
                should_draw = True
                is_active = (item["global_idx"] == active_idx)
            else:
                # کلمات آینده در حالت بدون فریم‌به‌فریم هم ترسیم نمی‌شوند
                should_draw = False

        if should_draw:
            # اعمال کم‌رنگ شدن کلمات قبل (گذشته) در صورت فعال بودن دکمه
            if not is_active and word_infos and item["global_idx"] < len(word_infos):
                w_info = word_infos[item["global_idx"]]
                if current_render_time >= w_info.end and getattr(style_config, 'fadeSurrounding', False):
                    alpha_factor = 0.35

            fill_color = active_text_color if (is_active and getattr(style_config, 'useActiveColor', True)) else base_text_color
            if word_infos and item["global_idx"] < len(word_infos):
                w_obj = word_infos[item["global_idx"]]
                if hasattr(w_obj, 'color') and w_obj.color:
                    fill_color = color_parser(w_obj.color, fill_color)

            final_alpha = int(fill_color[3] * alpha_factor)
            final_color = (fill_color[0], fill_color[1], fill_color[2], final_alpha)

            final_text_y = item["y"] + VERTICAL_CORRECTION

            draw.text((item["x"], final_text_y + y_offset), item["text"], font=font, fill=final_color, direction=getattr(style_config, 'text_direction', 'rtl'), language=getattr(style_config, 'lang_code', 'fa'))