<commit_before>import { SvgTarget } from '../animation';

export function svgAnimationToHtml(startSvg: string, svgTargets: SvgTarget[]) {
  // We assume here that the same duration and interpolator will be used for all targets.
  const duration = svgTargets[0].animations[0].duration;
  const interpolator = svgTargets[0].animations[0].interpolator;
  const animations = svgTargets.map(target => createCssAnimation(target.layerId, duration, interpolator));
  const keyframes = svgTargets.map(target => svgTargetToCssKeyframes(target.layerId, target));
  return `<!DOCTYPE html>
<html>
<head>
  <title>Shape Shifter CSS transition</title>
  <style>
    ${keyframes.join('\n')}
    ${animations.join('\n')}
  </style>
</head>
<body>
  ${startSvg}
</body>
</html>
`;
}

function createCssAnimation(layerId: string, duration: number, interpolator: string) {
  return `#${layerId} {
  animation: ${layerId}_animation ${duration}ms alternate infinite ${interpolator};
}`;
}

function svgTargetToCssKeyframes(layerId: string, svgTarget: SvgTarget) {
  const fromProps: string[] = [];
  for (const anim of svgTarget.animations) {
    fromProps.push(`${anim.propertyName}: ${anim.valueFrom}`);
  }
  const toProps: string[] = [];
  for (const anim of svgTarget.animations) {
    toProps.push(`${anim.propertyName}: ${anim.valueTo}`);
  }
  return `@keyframes ${layerId}_animation {
from {
  ${fromProps.join(';\n    ')}
}
to {
  ${toProps.join(';\n    ')}
}
}`;
}
<commit_msg>update css keyframes<commit_after>import { SvgTarget } from '../animation';

// TODO: add css prefixes to support all browsers
export function svgAnimationToHtml(svg: string, svgTargets: SvgTarget[]) {
  // We assume here that the same duration and interpolator will be used for all targets.
  const duration = svgTargets[0].animations[0].duration;
  const interpolator = svgTargets[0].animations[0].interpolator;
  const animations = svgTargets.map(target => createCssAnimation(target.layerId, duration, interpolator));
  const keyframes = svgTargets.map(target => svgTargetToCssKeyframes(target.layerId, target));
  return `<!DOCTYPE html>
<html>
<head>
  <title>Shape Shifter animation (CSS)</title>
  <style>
    body {
      position: absolute;
      margin: auto;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      width: 50%;
    }
    ${keyframes.join('\n')}
    ${animations.join('\n')}
  </style>
</head>
<body>
  ${svg}
</body>
</html>
`;
}

function createCssAnimation(layerId: string, duration: number, interpolator: string) {
  return `#${layerId} {
  animation: ${layerId}_anim ${duration}ms ${interpolator} forwards;
}`;
}

function svgTargetToCssKeyframes(layerId: string, svgTarget: SvgTarget) {
  const fromProps: string[] = [];
  for (const anim of svgTarget.animations) {
    fromProps.push(`${anim.propertyName}: ${anim.valueFrom}`);
  }
  const toProps: string[] = [];
  for (const anim of svgTarget.animations) {
    toProps.push(`${anim.propertyName}: ${anim.valueTo}`);
  }
  return `
    @keyframes ${layerId}_anim {
      from {
        ${fromProps.join(';\n      ')}
      }
      to {
        ${toProps.join(';\n      ')}
      }
    }`;
}

{'fraction_non_alphanumeric': 0.15726062143310082, 'fraction_numerical': 0.004438807863031071, 'mean_word_length': 4.130081300813008, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '407934', 'n_tokens_mistral': 1074, 'n_tokens_neox': 1058, 'n_words': 238}