User: # Role: Emoticon Content Generator

## Goals:
Generate content for an emoticon pack, including name, description, copyright information, and appreciation message.

## Constraints:
1. All content must be in Chinese.
2. Follow the specific requirements for each content type.

## Output:
The output should be a valid JSON object with the following structure:
{
  "name": "表情名称",
  "description": "表情介绍",
  "copyright": "版权信息",
  "appreciation": "赞赏引导语"
}

## Requirements:
1. 表情名称:
   - 不超过8个汉字
   - 5个汉字以内显示效果最佳
   - 不包含任何标点符号
   - 中文名称避免出现空格
   - 避免与已有表情专辑重名

2. 表情介绍:
   - 不超过80个汉字
   - 充分展现表情的形象特点或故事情节

3. 版权信息:
   - 不超过10个汉字
   - 已注册版权的请填写版权信息
   - 没有注册版权的则填写设计师或工作室名称
   - 尽量简短，可以用简写

4. 赞赏引导语:
   - 5~15个汉字
   - 文案可诙谐幽默，与表情有关联性
   - 示例：气泡狗如此可爱，发个赞赏可好？

## Context:
### Function Content:
const _ = require("lodash");
const { fabric } = require("fabric");
const { GifMaker } = require("../../../../utils/gif-maker");
const { getFont } = require("../../../../utils/fonts");
const { saveTestFrame } = require("../../../../utils/test-png");

const NUM = 16;
const BASE_SIZE = 240;

async function createGifs(output, scale = 2) {
  const SIZE = BASE_SIZE * scale;
  const frames = [];
  const { fontPath, fontFamily } = getFont();
  fabric.nodeCanvas.registerFont(fontPath, { family: fontFamily });
  const canvas = new fabric.StaticCanvas(null, { width: SIZE, height: SIZE });

  const chineseCharacters = "我爱你好吃喝玩乐学习工作睡觉跑步唱歌跳舞读书写字";
  const colors = [
    "#FF0000", "#00FF00", "#0000FF", "#FFFF00",
    "#FF00FF", "#00FFFF", "#FFA500", "#800080",
  ];
  const animations = ["bounce", "shake", "rotate", "scale", "fade"];

  for (let i = 0; i < NUM; i++) {
    const char = chineseCharacters[i];
    const color = _.sample(colors);
    const animation = _.sample(animations);

    const frame = await createSingleGif({
      output,
      canvas,
      char,
      color,
      animation,
      fontFamily,
      index: i,
      scale,
    });

    frames.push(frame);
  }

  return frames;
}

async function createSingleGif({
  output,
  canvas,
  char,
  color,
  animation,
  index,
  fontFamily,
  scale,
}) {
  const gifMaker = new GifMaker();
  gifMaker.setOutput(output, index);
  const text = new fabric.Text(char, {
    left: 120 * scale,
    top: 120 * scale,
    fontSize: 100 * scale,
    fill: color,
    fontFamily,
    originX: "center",
    originY: "center",
  });

  console.log("开始>> ", `${index}.gif`);
  for (let i = 0; i < 20; i++) {
    const progress = i / 19;
    canvas.clear();
    applyAnimation(text, animation, progress, scale);
    canvas.add(text);
    canvas.renderAll();

    await gifMaker.addFrame(canvas);
    await saveTestFrame(canvas, output, index, i);
  }

  await gifMaker.start();
  return gifMaker.frames;
}

function applyAnimation(text, animation, progress, scale) {
  switch (animation) {
    case "bounce":
      text.set("top", 120 * scale + Math.sin(progress * Math.PI) * 50 * scale);
      break;
    case "shake":
      text.set("left", 120 * scale + Math.sin(progress * Math.PI * 4) * 20 * scale);
      break;
    case "rotate":
      text.set("angle", progress * 360);
      break;
    case "scale":
      const scaleChange = 1 + Math.sin(progress * Math.PI) * 0.5;
      text.set("scaleX", scaleChange);
      text.set("scaleY", scaleChange);
      break;
    case "fade":
      text.set("opacity", Math.sin(progress * Math.PI));
      break;
  }
}

module.exports = { createGifs };


## Important Notes:
1. Ensure that the generated content is creative and unique.
2. The content should be related to the context provided in the function content.
3. If the function content doesn't provide enough context, create a fictional emoticon pack based on the general theme of the code.
User: # Role: Emoticon Content Generator

## Goals:
Generate content for an emoticon pack, including name, description, copyright information, and appreciation message.

## Constraints:
1. All content must be in Chinese.
2. Follow the specific requirements for each content type.

## Output:
The output should be a valid JSON object with the following structure:
{
  "name": "表情名称",
  "description": "表情介绍",
  "copyright": "版权信息",
  "appreciation": "赞赏引导语"
}

## Requirements:
1. 表情名称:
   - 不超过8个汉字
   - 5个汉字以内显示效果最佳
   - 不包含任何标点符号
   - 中文名称避免出现空格
   - 避免与已有表情专辑重名

2. 表情介绍:
   - 不超过80个汉字
   - 充分展现表情的形象特点或故事情节

3. 版权信息:
   - 不超过10个汉字
   - 已注册版权的请填写版权信息
   - 没有注册版权的则填写设计师或工作室名称
   - 尽量简短，可以用简写

4. 赞赏引导语:
   - 5~15个汉字
   - 文案可诙谐幽默，与表情有关联性
   - 示例：气泡狗如此可爱，发个赞赏可好？

## Context:
### Function Content:
const _ = require("lodash");
const { fabric } = require("fabric");
const { GifMaker } = require("../../../../utils/gif-maker");
const { getFont } = require("../../../../utils/fonts");
const { saveTestFrame } = require("../../../../utils/test-png");

const NUM = 16;
const BASE_SIZE = 240;

async function createGifs(output, scale = 2) {
  const SIZE = BASE_SIZE * scale;
  const frames = [];
  const { fontPath, fontFamily } = getFont();
  fabric.nodeCanvas.registerFont(fontPath, { family: fontFamily });
  const canvas = new fabric.StaticCanvas(null, { width: SIZE, height: SIZE });

  const chineseCharacters = "我爱你好吃喝玩乐学习工作睡觉跑步唱歌跳舞读书写字";
  const colors = [
    "#FF0000", "#00FF00", "#0000FF", "#FFFF00",
    "#FF00FF", "#00FFFF", "#FFA500", "#800080",
  ];
  const animations = ["bounce", "shake", "rotate", "scale", "fade"];

  for (let i = 0; i < NUM; i++) {
    const char = chineseCharacters[i];
    const color = _.sample(colors);
    const animation = _.sample(animations);

    const frame = await createSingleGif({
      output,
      canvas,
      char,
      color,
      animation,
      fontFamily,
      index: i,
      scale,
    });

    frames.push(frame);
  }

  return frames;
}

async function createSingleGif({
  output,
  canvas,
  char,
  color,
  animation,
  index,
  fontFamily,
  scale,
}) {
  const gifMaker = new GifMaker();
  gifMaker.setOutput(output, index);
  const text = new fabric.Text(char, {
    left: 120 * scale,
    top: 120 * scale,
    fontSize: 100 * scale,
    fill: color,
    fontFamily,
    originX: "center",
    originY: "center",
  });

  console.log("开始>> ", `${index}.gif`);
  for (let i = 0; i < 20; i++) {
    const progress = i / 19;
    canvas.clear();
    applyAnimation(text, animation, progress, scale);
    canvas.add(text);
    canvas.renderAll();

    await gifMaker.addFrame(canvas);
    await saveTestFrame(canvas, output, index, i);
  }

  await gifMaker.start();
  return gifMaker.frames;
}

function applyAnimation(text, animation, progress, scale) {
  switch (animation) {
    case "bounce":
      text.set("top", 120 * scale + Math.sin(progress * Math.PI) * 50 * scale);
      break;
    case "shake":
      text.set("left", 120 * scale + Math.sin(progress * Math.PI * 4) * 20 * scale);
      break;
    case "rotate":
      text.set("angle", progress * 360);
      break;
    case "scale":
      const scaleChange = 1 + Math.sin(progress * Math.PI) * 0.5;
      text.set("scaleX", scaleChange);
      text.set("scaleY", scaleChange);
      break;
    case "fade":
      text.set("opacity", Math.sin(progress * Math.PI));
      break;
  }
}

module.exports = { createGifs };


## Important Notes:
1. Ensure that the generated content is creative and unique.
2. The content should be related to the context provided in the function content.
3. If the function content doesn't provide enough context, create a fictional emoticon pack based on the general theme of the code.
Assistant: