Download raw (4.7 KB)
from svg.path import parse_path from svg.path.path import Move, Line, CubicBezier from bs4 import BeautifulSoup import re import os.path # height = 800 # width = height/(1920/1080) sources = [ ('digital-city-poster-weekend2-sara-sejin-chang-1920x1080.svg', '1920x1080-weekend2-sara-sejin-chang') ] fps = 25 still = [0, 2, 5, 5, 5, 5, 2, 3.5, 0] transition = [.6, .5, .5, .5, .5, .5, .5, .6] def parse_viewbox (viewboxstring): pattern = re.compile(r'(-?[\d\.]+) (-?[\d\.]+) (-?[\d\.]+) (-?[\d\.]+)') m = pattern.match(viewboxstring) return (float(m.group(1)), float(m.group(2)), float(m.group(3)), float(m.group(4))) def framecount (length): return int(length * fps) def get_translation (group): pattern = re.compile(r'translate\((-?[\d\.]+),\s*(-?[\d\.]+)\)') transform = group.get('transform') if transform: m = pattern.match(transform) if m: translation = (float(m.group(1)), float(m.group(2))) else: translation = (0, 0) else: translation = (0, 0) return translation def get_group_by_label (svg, label): for group in svg.find_all('g'): if group.get('inkscape:label') == label: return group def get_keypoints(svg): keypoints_layer = get_group_by_label(svg, 'keypoints') keypoints = keypoints_layer.find_all('circle') translation = get_translation(keypoints_layer) return [ complex(translation[0] + float(point.get('cx')), translation[1] + float(point.get('cy'))) for point in keypoints] def write_frame(f, svg, folder = ''): with open(os.path.join(folder, '{:05d}.svg'.format(f)), 'w') as o: o.write(svg.prettify(formatter=None) .replace('lineargradient', 'linearGradient') .replace('radialgradient', 'radialGradient') .replace('gradienttransform', 'gradientTransform') .replace('gradientunits', 'gradientUnits') .replace('spreadmethod', 'spreadMethod') .replace('viewbox', 'viewBox') .replace('flowroot', 'flowRoot') .replace('flowpara', 'flowPara') .replace('flowregion', 'flowRegion') .replace('textpath', 'textPath') .replace('startoffset', 'startOffset') .replace('spreadmethod', 'spreadMethod') .replace('clippath', 'clipPath')) o.close() for drawing, target in sources: print(drawing) with open(drawing, 'r') as handle: # use bs 4 to find paths soup = BeautifulSoup(handle.read(), 'lxml') svg = soup.find('svg') viewbox = parse_viewbox(svg['viewbox']) print(viewbox) width = viewbox[2] - viewbox[0] keypoints_layer = get_group_by_label(soup, 'keypoints') keypoints = sorted(get_keypoints(soup), key=lambda point: point.real) get_group_by_label(svg, 'sticky_title_ghost').extract() animation = get_group_by_label(soup, 'animation') translation = get_translation(animation) keypoints_layer.extract() f = 0 for k, center in enumerate(keypoints): if k > 0: # Generate transition for i in range(framecount(transition[min(k, len(transition) - 1)])): t = i / float(framecount(transition[min(k, len(transition) - 1)])) d = keypoints[k].real - keypoints[k-1].real x = translation[0] - keypoints[k-1].real - (t * d) + (float(width) / 2) y = translation[1] animation['transform'] = 'translate({}, {})'.format(x, y) if k > 2 and k < 6: # Compensate the movement of the animated layer to # make the title 'stick' in its position get_group_by_label(svg, 'sticky_title')['transform'] = 'translate({},{})'.format(sticky_x - x, sticky_y - y) get_group_by_label(svg, 'text')['style'] = 'display:none;visibility:hidden;' write_frame(f, svg, folder=os.path.join(target, 'svg')) f += 1 if framecount(still[min(k, len(still) - 1)]) > 0: # Generate still frames x = translation[0] + (-1 * (center.real - (float(width) / 2))) y = translation[1] if k > 2 and k < 6: # Compensate the movement of the animated layer to # make the title 'stick' in its position get_group_by_label(svg, 'sticky_title')['transform'] = 'translate({},{})'.format(sticky_x - x, sticky_y - y) animation['transform'] = 'translate({}, {})'.format(x, y) get_group_by_label(svg, 'text')['style'] = 'display:inline;visibility:visible;' for i in range(framecount(still[min(k, len(still) - 1)])): write_frame(f, svg, folder=os.path.join(target, 'svg')) f += 1 # print(path, 'translate({}, {})'.format(center.real - (width / 2), 0)) if k == 2: # Title hollands kabinet from frame 2 needs to stick untill # frame 5 sticky_x = translation[0] sticky_y = translation[1] # output = svgwrite.Drawing(filename="frames/output.svg", size=(width, height))