post / templates /showcase_arabic.py
ex510's picture
Upload 3 files
ab4b623 verified
"""
Template: showcase_arabic
تمبلت عرض المنتجات بالعربي
خلفية بنفسجية + نصوص عربية + badge ذهبي
"""
from PIL import Image, ImageDraw
from .base import BaseTemplate, RenderRequest
class ShowcaseArabic(BaseTemplate):
NAME = "showcase_arabic"
DESCRIPTION = "تمبلت عرض منتج احترافي — خلفية بنفسجية وبادج ذهبي"
AUTHOR = "your_name"
# ألوان افتراضية
DEFAULT_BG_LEFT = (98, 70, 180)
DEFAULT_BG_RIGHT = (15, 15, 45)
# ============================================================
def _create_bg(self, w, h, cl, cr):
img = Image.new('RGBA', (w, h))
d = ImageDraw.Draw(img)
for x in range(w):
if x < w * 0.6:
r2 = x / (w * 0.6)
c = (
int(cl[0] * (1 - r2 * 0.3)),
int(cl[1] * (1 - r2 * 0.3)),
int(cl[2] * (1 - r2 * 0.1)),
255
)
else:
r2 = (x - w * 0.6) / (w * 0.4)
c = (
int(cl[0] * 0.7 * (1-r2) + cr[0] * r2),
int(cl[1] * 0.7 * (1-r2) + cr[1] * r2),
int(cl[2] * 0.9 * (1-r2) + cr[2] * r2),
255
)
d.line([(x, 0), (x, h)], fill=c)
return img
def _draw_badge(self, draw, cx, cy, r, lines, font):
if r < 5:
return
draw.ellipse([cx-r-8, cy-r-8, cx+r+8, cy+r+8], fill=(160, 130, 10))
draw.ellipse([cx-r, cy-r, cx+r, cy+r ], fill=(200, 160, 20))
total_h = sum(font.getbbox(l)[3] for l in lines) + (len(lines)-1) * 4
y = cy - total_h // 2
for line in lines:
b = font.getbbox(line)
draw.text((cx - (b[2]-b[0])//2, y), line, font=font, fill=(255, 255, 255))
y += b[3] + 4
# ============================================================
def make_frame(self, t, req: RenderRequest, product_img, logo_img):
W, H, D = req.width, req.height, req.duration
cl = self.parse_color(req.bg_left, self.DEFAULT_BG_LEFT)
cr = self.parse_color(req.bg_right, self.DEFAULT_BG_RIGHT)
# خلفية
frame = self._create_bg(W, H, cl, cr)
# زخرفة دوائر
ov = Image.new('RGBA', (W, H), (0, 0, 0, 0))
od = ImageDraw.Draw(ov)
od.ellipse([W*.45, -H*.3, W*1.2, H*1.3], fill=(30, 20, 70, 80))
od.ellipse([W*.55, H*.3, W*1.1, H*1.1], fill=(20, 15, 50, 60))
frame = Image.alpha_composite(frame, ov)
ft = self.load_font(72)
fd = self.load_font(48)
fc = self.load_font(30)
# --- صورة المنتج ---
ip = min(1.0, t / (D * 0.4))
io = int((1 - self.ease_out(ip)) * -W * 0.5)
if product_img:
pw = int(W * 0.42)
ph = int(product_img.height * pw / product_img.width)
rs = product_img.resize((pw, ph), Image.LANCZOS)
px = int(W * 0.02) + io
py = (H - ph) // 2
frame.paste(rs, (px, py), rs if rs.mode == 'RGBA' else None)
tl = Image.new('RGBA', (W, H), (0, 0, 0, 0))
td = ImageDraw.Draw(tl)
# --- نصوص ---
tp = min(1.0, max(0.0, (t - D*.2) / (D*.4)))
to = int((1 - self.ease_out(tp)) * -H * 0.3)
ta = int(self.ease_out(tp) * 255)
RX = int(W * 0.95)
ty = int(H * 0.15) + to
for i, line in enumerate(req.title.replace('\\n', '\n').split('\n')):
b = ft.getbbox(line)
tw = b[2] - b[0]
td.text((RX - tw, ty + i*90), line, font=ft, fill=(255, 255, 255, ta))
if req.discount:
b = fd.getbbox(req.discount)
dw = b[2] - b[0]
td.text((RX - dw, int(H*.55) + to), req.discount,
font=fd, fill=(220, 160, 40, ta))
# --- معلومات اتصال ---
cp = min(1.0, max(0.0, (t - D*.5) / (D*.3)))
ca = int(self.ease_out(cp) * 255)
cy2 = int(H * 0.68)
for i, txt in enumerate([req.phone, req.website]):
if not txt:
continue
b = fc.getbbox(txt)
tw = b[2] - b[0]
td.text((RX - tw, cy2 + i*42), txt,
font=fc, fill=(200-i*20, 200-i*20, 200-i*20, ca))
frame = Image.alpha_composite(frame, tl)
# --- badge ---
if req.badge:
bp = min(1.0, max(0.0, (t - D*.1) / (D*.3)))
bs = self.ease_out(bp)
if bs > 0.05:
bl = Image.new('RGBA', (W, H), (0, 0, 0, 0))
bd = ImageDraw.Draw(bl)
self._draw_badge(bd,
int(W*.08), int(H*.18),
int(70 * bs),
req.badge.replace('\\n', '\n').split('\n'),
self.load_font(int(32 * bs)))
frame = Image.alpha_composite(frame, bl)
return frame.convert('RGB')