Sign in

vitor-internCopy the usernamekit-logo-remix-remix

variations.py

In source/

mainHistory

Preview

Code5.3 KiB
"""Alternate logo arrangements built from the approved contours."""
from copy import deepcopy
from pathlib import Path
import subprocess
import xml.etree.ElementTree as E
from .logo import render, NS, element
from .design import UNO_BLUE

OPTIONS = [
 ('01-classic-grid','Classic / fading grid','Original proportions and square frame'),
 ('02-blue-reverse','Blue / white lettering','Full color solids on Uno blue'),
 ('03-rounded-frame','Rounded / open frame','Soft frame with the original composition'),
 ('04-rounded-blue','Rounded / blue field','White lettering in a rounded blue container'),
 ('05-wordmark-blue','Wordmark / blue','Wide KIT lettering without the illustration'),
 ('06-wordmark-reverse','Wordmark / reverse','White lettering on an Uno-blue field'),
 ('07-horizontal','Horizontal / full color','Geometric symbol paired with the wordmark'),
 ('08-compact','Compact / rounded tile','A simple wordmark for smaller placements'),
 ('09-monochrome','Monochrome / reverse','White solids with blue construction edges'),
]

def variant(index):
 root=E.fromstring(render(grid=index==0))
 children=list(root)
 bg=next(e for e in children if e.tag==NS+'rect')
 solids=next(e for e in children if e.tag==NS+'svg')
 frame=next(e for e in children if e.tag==NS+'path' and e.get('fill')=='none')
 letters=children[-3:]
 blue=index in [1,3,5,7,8]
 if blue:
  bg.set('fill',UNO_BLUE)
  for e in letters:e.set('fill','white')
  frame.set('stroke','white')
 if index in [2,3,7,8]:
  root.remove(frame)
  if index==2:
   E.SubElement(root,NS+'rect',{'x':'3.35','y':'3.35','width':'73.3','height':'73.3','rx':'7','fill':'none','stroke':UNO_BLUE,'stroke-width':'1.682'})
  else:
   bg.set('rx','9')
 if index in [1,3]:
  sphere=next(e for e in solids if e.get('aria-label')=='Sphere')
  circle=next(iter(sphere))
  # A fine keyline preserves the blue sphere silhouette against the blue field.
  rim=deepcopy(circle)
  rim.attrib.update({'fill':'none','stroke':'white','stroke-width':'1.8','stroke-opacity':'.7'})
  sphere.append(rim)
 if index in [4,5]:
  root.remove(solids)
  root.remove(frame)
  root.set('viewBox','0 0 80 38')
  bg.set('height','38')
  for e in letters:e.set('transform','translate(0 -41.5)')
 if index==6:
  root.remove(frame)
  root.set('viewBox','0 0 154 60')
  bg.set('width','154');bg.set('height','60')
  solids.set('x','-2');solids.set('y','3')
  for e in letters:e.set('transform','translate(75 -30.5)')
 if index==7:
  root.remove(solids)
  for e in letters:e.set('transform','translate(6.4 -21) scale(.84)')
 if index==8:
  for e in solids.iter():
   if e.tag in [NS+'path',NS+'circle']:
    e.set('fill','white');e.set('stroke',UNO_BLUE)
    e.set('stroke-width','2.4');e.set('stroke-linejoin','round')
 # Remove unused gradients for lightweight exports.
 defs=root.find(NS+'defs')
 used=' '.join(v for e in root.iter() if e is not defs for v in e.attrib.values())
 for e in list(defs):
  if 'url(#'+e.get('id','')+')' not in used:defs.remove(e)
 title=root.find(NS+'title');title.text='KIT — '+OPTIONS[index][1]
 root.find(NS+'desc').text=OPTIONS[index][2]
 root.set('width','1000');root.set('height','1000')
 if index in [4,5]:root.set('width','1400');root.set('height','665')
 if index==6:root.set('width','1540');root.set('height','600')
 return root

def build(root):
 art=root/'art'/'variations';art.mkdir(parents=True,exist_ok=True)
 previews=root/'previews'/'variations';previews.mkdir(parents=True,exist_ok=True)
 sheet=E.Element(NS+'svg',{'width':'1920','height':'2016','viewBox':'0 0 1920 2016'})
 element(sheet,'rect',width=1920,height=2016,fill='#f3f5f8')
 element(sheet,'text',x=48,y=64,fill='#0067ed',font_family='Helvetica, Arial, sans-serif',font_size=30,font_weight=700).text='KIT / Brand variations'
 element(sheet,'text',x=48,y=98,fill='#536174',font_family='Helvetica, Arial, sans-serif',font_size=17).text='Uno blue · original geometry · wide lettering'
 for i,(name,title,description) in enumerate(OPTIONS):
  svg=variant(i)
  path=art/(name+'.svg');path.write_text(E.tostring(svg,encoding='unicode'))
  subprocess.run(['rsvg-convert','-o',str(previews/(name+'.png')),str(path)],check=True)
  x=48+(i%3)*624;y=136+(i//3)*624
  element(sheet,'rect',x=x,y=y,width=600,height=600,rx=16,fill='white')
  nested=deepcopy(svg)
  nested.attrib.update({'x':str(x+44),'y':str(y+28),'width':'512','height':'470'})
  # Prefix paint IDs in the sheet so each cell owns its gradients.
  ids={e.get('id'):f'v{i}-'+e.get('id') for e in nested.iter() if e.get('id')}
  for e in nested.iter():
   for key,value in list(e.attrib.items()):
    if key=='id':e.set(key,ids[value])
    elif key=='aria-labelledby':e.set(key,' '.join(ids.get(v,v) for v in value.split()))
    else:
     for old,new in ids.items():value=value.replace('url(#'+old+')','url(#'+new+')')
     e.set(key,value)
  sheet.append(nested)
  element(sheet,'text',x=x+28,y=y+539,fill='#0067ed',font_family='Helvetica, Arial, sans-serif',font_size=20,font_weight=700).text=f'{i+1:02}  {title}'
  element(sheet,'text',x=x+28,y=y+570,fill='#536174',font_family='Helvetica, Arial, sans-serif',font_size=15).text=description
 path=art/'comparison.svg';path.write_text(E.tostring(sheet,encoding='unicode'))
 subprocess.run(['rsvg-convert','-o',str(previews/'comparison.png'),str(path)],check=True)
 print('Built nine SVG and PNG variations plus comparison sheet.')

if __name__=='__main__':build(Path(__file__).resolve().parent.parent)

Files

Loading files

Details

Size
5.3 KiB (5,431 bytes)
Object ID
6554fac…f21Copy the object ID
  • AGENTS.md
  • README.md
  • build.py
  • cover.png
  • manifest.json
Size
5.3 KiB (5,431 bytes)
Object ID
6554fac…f21Copy the object ID
Storage
Stored as one object
Size
5.3 KiB (5,431 bytes)
Object ID
6554fac…f21Copy the object ID
Storage
Stored as one object
Verification