Skip to content

Commit

Permalink
chore: add function-templates using framebased animation
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasdinonolte committed May 7, 2022
1 parent e4f71b5 commit 1b54892
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/create-mechanic/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added
- Added function templates for framebased animations

## 1.2.0 - 2022-02-14

### Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@mechanic-design/engine-canvas": "^2.0.0-beta.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { drawLoop } from "@mechanic-design/core";

export const handler = async ({ inputs, mechanic }) => {
const { width, height, text, color1, color2, radiusPercentage, turns } =
inputs;

const center = [width / 2, height / 2];
const radius = ((height / 2) * radiusPercentage) / 100;
let angle = 0;

const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;

const ctx = canvas.getContext("2d");

drawLoop(({ frameCount, stop }) => {
ctx.fillStyle = "#F4F4F4";
ctx.fillRect(0, 0, width, height);

ctx.fillStyle = color1;
ctx.beginPath();
ctx.arc(
center[0],
center[1],
radius,
Math.PI + angle,
2 * Math.PI + angle,
false
);
ctx.fill();

ctx.fillStyle = color2;
ctx.beginPath();
ctx.arc(center[0], center[1], radius, 0 + angle, Math.PI + angle, false);
ctx.fill();

ctx.fillStyle = "#000000";
ctx.font = `${height / 10}px sans-serif`;
ctx.textAlign = "center";
ctx.strokeText(text, width / 2, height - height / 20);
ctx.fillText(text, width / 2, height - height / 20);

if (angle < turns * 2 * Math.PI) {
mechanic.frame(canvas);
angle = frameCount;
} else {
stop();
mechanic.done(canvas);
}
}, mechanic.frameRate);
};

export const inputs = {
width: {
type: "number",
default: 400,
},
height: {
type: "number",
default: 300,
},
text: {
type: "text",
default: "mechanic",
},
color1: {
type: "color",
model: "hex",
default: "#E94225",
},
color2: {
type: "color",
model: "hex",
default: "#002EBB",
},
radiusPercentage: {
type: "number",
default: 40,
min: 0,
max: 100,
slider: true,
},
turns: {
type: "number",
default: 3,
},
};

export const presets = {
medium: {
width: 800,
height: 600,
},
large: {
width: 1600,
height: 1200,
},
};

export const settings = {
engine: require("@mechanic-design/engine-canvas"),
animated: true,
frameRate: 60,
};
15 changes: 15 additions & 0 deletions packages/create-mechanic/function-templates/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const options = [
type: "Canvas",
dir: "canvas-video",
},
{
name: "Vanilla JS Video (Framebased)",
type: "Canvas",
dir: "canvas-video-framebased",
},
{
name: "Vanilla JS Image",
type: "SVG",
Expand All @@ -19,6 +24,11 @@ const options = [
type: "SVG",
dir: "svg-video",
},
{
name: "Vanilla JS Video (Framebased)",
type: "Canvas",
dir: "svg-video-framebased",
},
{
name: "p5.js Image",
type: "Canvas",
Expand All @@ -39,6 +49,11 @@ const options = [
type: "SVG",
dir: "react-video",
},
{
name: "React Video (Framebased)",
type: "SVG",
dir: "react-video-framebased",
},
];

module.exports = options.reduce((acc, cur) => {
Expand Down
2 changes: 2 additions & 0 deletions packages/create-mechanic/function-templates/p5-video/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const handler = ({ inputs, mechanic, sketch }) => {

sketch.setup = () => {
sketch.createCanvas(width, height);
sketch.frameRate(mechanic.frameRate);
};

sketch.draw = () => {
Expand Down Expand Up @@ -89,4 +90,5 @@ export const presets = {
export const settings = {
engine: require("@mechanic-design/engine-p5"),
animated: true,
frameRate: 60,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@mechanic-design/engine-react": "^2.0.0-beta.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import React, { useEffect, useRef } from "react";
import { useDrawLoop } from "@mechanic-design/engine-react";

export const handler = ({ inputs, mechanic }) => {
const { width, height, text, color1, color2, radiusPercentage, turns } =
inputs;

const center = [width / 2, height / 2];
const radius = ((height / 2) * radiusPercentage) / 100;
const angle = useRef(0);

const isPlaying = useRef(true);
const frameCount = useDrawLoop(isPlaying.current, mechanic.frameRate);

useEffect(() => {
if (angle.current < turns * 360) {
mechanic.frame();
angle.current = frameCount;
} else if (isPlaying.current) {
isPlaying.current = false;
mechanic.done();
}
}, [frameCount]);

return (
<svg width={width} height={height}>
<rect fill="#F4F4F4" width={width} height={height} />
<g transform={`translate(${center[0]}, ${center[1]})`}>
<g transform={`rotate(${angle.current})`}>
<path
d={`M ${radius} 0
A ${radius} ${radius}, 0, 0, 0, ${-radius} 0 Z`}
fill={color1}
/>
<path
d={`M ${-radius} 0
A ${radius} ${radius}, 0, 0, 0, ${radius} 0 Z`}
fill={color2}
/>
</g>
<text
x={0}
y={height / 2 - height / 20}
textAnchor="middle"
fontWeight="bold"
fontFamily="sans-serif"
fontSize={height / 10}
>
{text}
</text>
</g>
</svg>
);
};

export const inputs = {
width: {
type: "number",
default: 400,
},
height: {
type: "number",
default: 300,
},
text: {
type: "text",
default: "mechanic",
},
color1: {
type: "color",
model: "hex",
default: "#E94225",
},
color2: {
type: "color",
model: "hex",
default: "#002EBB",
},
radiusPercentage: {
type: "number",
default: 40,
min: 0,
max: 100,
slider: true,
},
turns: {
type: "number",
default: 3,
},
};

export const presets = {
medium: {
width: 800,
height: 600,
},
large: {
width: 1600,
height: 1200,
},
};

export const settings = {
engine: require("@mechanic-design/engine-react"),
animated: true,
frameRate: 60,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@mechanic-design/engine-svg": "^2.0.0-beta.4"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { drawLoop } from "@mechanic-design/core";

export const handler = ({ inputs, mechanic }) => {
const { width, height, text, color1, color2, radiusPercentage, turns } =
inputs;

const center = [width / 2, height / 2];
const radius = ((height / 2) * radiusPercentage) / 100;

let angle = 0;
drawLoop(({ frameCount, stop }) => {
const svg = `<svg width="${width}" height="${height}">
<rect fill="#F4F4F4" width="${width}" height="${height}" />
<g transform="translate(${center[0]}, ${center[1]})">
<g transform="rotate(${angle})">
<path
d="M ${radius} 0
A ${radius} ${radius}, 0, 0, 0, ${-radius} 0 Z"
fill="${color1}"
/>
<path
d="M ${-radius} 0
A ${radius} ${radius}, 0, 0, 0, ${radius} 0 Z"
fill="${color2}"
/>
</g>
<text
x="0"
y="${height / 2 - height / 20}"
text-anchor="middle"
font-weight="bold"
font-family="sans-serif"
font-size="${height / 10}"
>
${text}
</text>
</g>
</svg>`;

if (angle < turns * 360) {
mechanic.frame(svg);
angle = frameCount;
} else {
stop();
mechanic.done(svg);
}
}, mechanic.frameRate);
};

export const inputs = {
width: {
type: "number",
default: 400,
},
height: {
type: "number",
default: 300,
},
text: {
type: "text",
default: "mechanic",
},
color1: {
type: "color",
model: "hex",
default: "#E94225",
},
color2: {
type: "color",
model: "hex",
default: "#002EBB",
},
radiusPercentage: {
type: "number",
default: 40,
min: 0,
max: 100,
slider: true,
},
turns: {
type: "number",
default: 3,
},
};

export const presets = {
medium: {
width: 800,
height: 600,
},
large: {
width: 1600,
height: 1200,
},
};

export const settings = {
engine: require("@mechanic-design/engine-svg"),
animated: true,
frameRate: 60,
};

0 comments on commit 1b54892

Please sign in to comment.