feat: add markdown logs (#138)

This commit is contained in:
Jacob
2023-01-18 01:08:06 +01:00
committed by GitHub
parent 063aede084
commit e42447a0c0
36 changed files with 465 additions and 128 deletions

View File

@@ -3,5 +3,6 @@
"singleQuote": true,
"printWidth": 80,
"trailingComma": "all",
"arrowParens": "avoid"
"arrowParens": "avoid",
"proseWrap": "always"
}

209
package-lock.json generated
View File

@@ -4609,6 +4609,10 @@
"resolved": "packages/examples",
"link": true
},
"node_modules/@motion-canvas/internal": {
"resolved": "packages/internal",
"link": true
},
"node_modules/@motion-canvas/player": {
"resolved": "packages/player",
"link": true
@@ -5144,6 +5148,60 @@
"vite": ">=2.0.0-beta.3"
}
},
"node_modules/@rollup/plugin-typescript": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.0.0.tgz",
"integrity": "sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"resolve": "^1.22.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^2.14.0||^3.0.0",
"tslib": "*",
"typescript": ">=3.7.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
},
"tslib": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-typescript/node_modules/@rollup/pluginutils": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
"dev": true,
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
}
},
"node_modules/@rollup/plugin-typescript/node_modules/@types/estree": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
"dev": true
},
"node_modules/@rollup/pluginutils": {
"version": "4.2.1",
"dev": true,
@@ -11184,6 +11242,15 @@
"he": "bin/he"
}
},
"node_modules/highlight.js": {
"version": "11.7.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
"dev": true,
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/history": {
"version": "4.10.1",
"license": "MIT",
@@ -13671,9 +13738,9 @@
}
},
"node_modules/marked": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz",
"integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==",
"version": "4.2.12",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
"integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
"dev": true,
"bin": {
"marked": "bin/marked.js"
@@ -19054,6 +19121,23 @@
"dev": true,
"license": "0BSD"
},
"node_modules/ttypescript": {
"version": "1.5.15",
"resolved": "https://registry.npmjs.org/ttypescript/-/ttypescript-1.5.15.tgz",
"integrity": "sha512-48ykDNHzFnPMnv4hYX1P8Q84TvCZyL1QlFxeuxsuZ48X2+ameBgPenvmCkHJtoOSxpoWTWi8NcgNrRnVDOmfSg==",
"dev": true,
"dependencies": {
"resolve": ">=1.9.0"
},
"bin": {
"ttsc": "bin/tsc",
"ttsserver": "bin/tsserver"
},
"peerDependencies": {
"ts-node": ">=8.0.2",
"typescript": ">=3.2.2"
}
},
"node_modules/type-check": {
"version": "0.4.0",
"devOptional": true,
@@ -20611,13 +20695,14 @@
},
"packages/2d": {
"name": "@motion-canvas/2d",
"version": "12.0.1",
"version": "12.1.0",
"license": "MIT",
"dependencies": {
"code-fns": "^0.7.0"
},
"devDependencies": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"@motion-canvas/internal": "0.0.0",
"typescript": "^4.7.4"
},
"peerDependencies": {
@@ -20626,7 +20711,7 @@
},
"packages/core": {
"name": "@motion-canvas/core",
"version": "12.0.0",
"version": "12.1.0",
"license": "MIT",
"dependencies": {
"@types/chroma-js": "^2.1.4",
@@ -20634,6 +20719,8 @@
"mix-color": "^1.1.2"
},
"devDependencies": {
"@motion-canvas/internal": "0.0.0",
"@rollup/plugin-typescript": "^11.0.0",
"@types/dom-webcodecs": "^0.1.4",
"canvas-5-polyfill": "^0.1.5",
"typescript": "^4.7.4",
@@ -20646,7 +20733,7 @@
},
"packages/create": {
"name": "@motion-canvas/create",
"version": "12.0.1",
"version": "12.1.0",
"license": "MIT",
"dependencies": {
"prompts": "^2.4.2"
@@ -20655,10 +20742,10 @@
"create-motion-canvas": "index.js"
},
"devDependencies": {
"@motion-canvas/2d": "^12.0.1",
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/ui": "^12.0.0",
"@motion-canvas/vite-plugin": "^12.0.0"
"@motion-canvas/2d": "^12.1.0",
"@motion-canvas/core": "^12.1.0",
"@motion-canvas/ui": "^12.1.0",
"@motion-canvas/vite-plugin": "^12.1.0"
}
},
"packages/docs": {
@@ -20717,12 +20804,21 @@
"vite": "^3.0.5"
}
},
"packages/internal": {
"name": "@motion-canvas/internal",
"version": "0.0.0",
"devDependencies": {
"highlight.js": "^11.7.0",
"marked": "^4.2.12",
"ttypescript": "^1.5.15"
}
},
"packages/player": {
"name": "@motion-canvas/player",
"version": "12.0.0",
"version": "12.1.0",
"license": "MIT",
"devDependencies": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"terser": "^5.16.1",
"typescript": "^4.6.4",
"vite": "^3.0.4"
@@ -20747,12 +20843,13 @@
},
"packages/ui": {
"name": "@motion-canvas/ui",
"version": "12.0.0",
"version": "12.1.0",
"license": "MIT",
"devDependencies": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"@preact/preset-vite": "^2.3.0",
"clsx": "^1.2.1",
"highlight.js": "^11.7.0",
"preact": "10.7.3",
"source-map-js": "^1.0.2",
"typescript": "^4.6.4",
@@ -20773,12 +20870,13 @@
},
"packages/vite-plugin": {
"name": "@motion-canvas/vite-plugin",
"version": "12.0.0",
"version": "12.1.0",
"license": "MIT",
"dependencies": {
"mime-types": "^2.1.35"
},
"devDependencies": {
"@motion-canvas/internal": "0.0.0",
"@types/mime-types": "^2.1.1",
"typescript": "^4.7.4",
"vite": "^3.0.9"
@@ -23901,7 +23999,8 @@
"@motion-canvas/2d": {
"version": "file:packages/2d",
"requires": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"@motion-canvas/internal": "0.0.0",
"code-fns": "^0.7.0",
"typescript": "^4.7.4"
}
@@ -23909,6 +24008,8 @@
"@motion-canvas/core": {
"version": "file:packages/core",
"requires": {
"@motion-canvas/internal": "0.0.0",
"@rollup/plugin-typescript": "*",
"@types/chroma-js": "^2.1.4",
"@types/dom-webcodecs": "^0.1.4",
"canvas-5-polyfill": "^0.1.5",
@@ -23922,10 +24023,10 @@
"@motion-canvas/create": {
"version": "file:packages/create",
"requires": {
"@motion-canvas/2d": "^12.0.1",
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/ui": "^12.0.0",
"@motion-canvas/vite-plugin": "^12.0.0",
"@motion-canvas/2d": "^12.1.0",
"@motion-canvas/core": "^12.1.0",
"@motion-canvas/ui": "^12.1.0",
"@motion-canvas/vite-plugin": "^12.1.0",
"prompts": "^2.4.2"
}
},
@@ -23973,10 +24074,18 @@
"vite": "^3.0.5"
}
},
"@motion-canvas/internal": {
"version": "file:packages/internal",
"requires": {
"highlight.js": "^11.7.0",
"marked": "^4.2.12",
"ttypescript": "^1.5.15"
}
},
"@motion-canvas/player": {
"version": "file:packages/player",
"requires": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"terser": "^5.16.1",
"typescript": "^4.6.4",
"vite": "^3.0.4"
@@ -23995,9 +24104,10 @@
"@motion-canvas/ui": {
"version": "file:packages/ui",
"requires": {
"@motion-canvas/core": "^12.0.0",
"@motion-canvas/core": "^12.1.0",
"@preact/preset-vite": "^2.3.0",
"clsx": "*",
"clsx": "^1.2.1",
"highlight.js": "^11.7.0",
"preact": "10.7.3",
"source-map-js": "^1.0.2",
"typescript": "^4.6.4",
@@ -24013,6 +24123,7 @@
"@motion-canvas/vite-plugin": {
"version": "file:packages/vite-plugin",
"requires": {
"@motion-canvas/internal": "0.0.0",
"@types/mime-types": "^2.1.1",
"mime-types": "^2.1.35",
"typescript": "^4.7.4",
@@ -24381,6 +24492,35 @@
"@rollup/pluginutils": "^4.1.0"
}
},
"@rollup/plugin-typescript": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.0.0.tgz",
"integrity": "sha512-goPyCWBiimk1iJgSTgsehFD5OOFHiAknrRJjqFCudcW8JtWiBlK284Xnn4flqMqg6YAjVG/EE+3aVzrL5qNSzQ==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^5.0.1",
"resolve": "^1.22.1"
},
"dependencies": {
"@rollup/pluginutils": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
"dev": true,
"requires": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^2.3.1"
}
},
"@types/estree": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==",
"dev": true
}
}
},
"@rollup/pluginutils": {
"version": "4.2.1",
"dev": true,
@@ -28220,6 +28360,12 @@
"he": {
"version": "1.2.0"
},
"highlight.js": {
"version": "11.7.0",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz",
"integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==",
"dev": true
},
"history": {
"version": "4.10.1",
"requires": {
@@ -29843,9 +29989,9 @@
"version": "1.0.4"
},
"marked": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz",
"integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==",
"version": "4.2.12",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.2.12.tgz",
"integrity": "sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw==",
"dev": true
},
"mdast-squeeze-paragraphs": {
@@ -33211,6 +33357,15 @@
}
}
},
"ttypescript": {
"version": "1.5.15",
"resolved": "https://registry.npmjs.org/ttypescript/-/ttypescript-1.5.15.tgz",
"integrity": "sha512-48ykDNHzFnPMnv4hYX1P8Q84TvCZyL1QlFxeuxsuZ48X2+ameBgPenvmCkHJtoOSxpoWTWi8NcgNrRnVDOmfSg==",
"dev": true,
"requires": {
"resolve": ">=1.9.0"
}
},
"type-check": {
"version": "0.4.0",
"devOptional": true,

View File

@@ -8,8 +8,8 @@
"main": "lib/scenes/index.js",
"types": "./lib/scenes/index.d.ts",
"scripts": {
"build": "tsc",
"watch": "tsc -w"
"build": "ttsc",
"watch": "ttsc -w"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/motion-canvas"
@@ -28,6 +28,7 @@
},
"devDependencies": {
"@motion-canvas/core": "^12.1.0",
"@motion-canvas/internal": "0.0.0",
"typescript": "^4.7.4"
},
"dependencies": {

View File

@@ -1,2 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/// <reference types="@motion-canvas/core/project" />
/// <reference types="@motion-canvas/internal" />

View File

@@ -17,7 +17,12 @@
"paths": {
"@motion-canvas/2d/lib/jsx-runtime": ["jsx-runtime.ts"]
},
"types": ["node"]
"types": ["node"],
"plugins": [
{
"transform": "@motion-canvas/internal/transformers/markdown-literals.js"
}
]
},
"include": ["src"]
}

View File

@@ -6,8 +6,8 @@
"author": "motion-canvas",
"license": "MIT",
"scripts": {
"build": "tsc -p tsconfig.build.json",
"watch": "tsc -p tsconfig.build.json -w",
"build": "ttsc -p tsconfig.build.json",
"watch": "ttsc -p tsconfig.build.json -w",
"test": "vitest"
},
"publishConfig": {
@@ -31,6 +31,8 @@
"mix-color": "^1.1.2"
},
"devDependencies": {
"@motion-canvas/internal": "0.0.0",
"@rollup/plugin-typescript": "^11.0.0",
"@types/dom-webcodecs": "^0.1.4",
"canvas-5-polyfill": "^0.1.5",
"typescript": "^4.7.4",

View File

@@ -1,3 +1,3 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/// <reference types="@motion-canvas/internal" />
declare type Callback = (...args: any[]) => void;

View File

@@ -0,0 +1,6 @@
To retrieve the referenced object, invoke the reference like a function:
```ts
ref.value; // wrong
ref(); // correct
```

View File

@@ -0,0 +1,7 @@
To set the referenced object, pass it to the reference like you would to a
function:
```ts
ref.value = object; // wrong
ref(object); // correct
```

View File

@@ -1,4 +1,6 @@
import {deprecate} from './deprecate';
import getReferenceValue from './__logs__/get-reference-value.md';
import setReferenceValue from './__logs__/set-reference-value.md';
export interface ReferenceReceiver<T> {
(reference: T): void;
@@ -27,16 +29,14 @@ export function createRef<T>(): Reference<T> {
get: deprecate(
() => value,
'get Reference.value has been deprecated.',
`To retrieve the referenced object, invoke the reference like a function:
<pre>ref.value; // wrong\nref(); // correct</pre>`,
getReferenceValue,
),
set: deprecate(
newValue => {
value = newValue;
},
'set Reference.value has been deprecated.',
`To set the referenced object, pass it to the reference like you would to a function:
<pre>ref.value = object; // wrong\nref(object); // correct</pre>`,
setReferenceValue,
),
});

View File

@@ -11,7 +11,8 @@ export function useThread(): Thread {
if (!thread) {
throw new DetailedError(
'The thread is not available in the current context.',
`<code>useThread()</code> can only be called from within generator functions.
// language=markdown
`\`useThread()\` can only be called from within generator functions.
It's not available during rendering.`,
);
}

View File

@@ -19,7 +19,12 @@
"paths": {
"@motion-canvas/core/lib/jsx-runtime": ["jsx-runtime.ts"]
},
"types": ["node", "dom-webcodecs"]
"types": ["node", "dom-webcodecs"],
"plugins": [
{
"transform": "@motion-canvas/internal/transformers/markdown-literals.js"
}
]
},
"include": ["src"]
}

View File

@@ -1,6 +1,8 @@
import {defineConfig} from 'vitest/config';
import markdownLiterals from '@motion-canvas/internal/vite/markdown-literals';
export default defineConfig({
plugins: [markdownLiterals()],
test: {
setupFiles: ['./vitest.setup.ts'],
environment: 'jsdom',

4
packages/internal/index.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module '*.md' {
const value: string;
export default value;
}

View File

@@ -0,0 +1,10 @@
{
"name": "@motion-canvas/internal",
"private": true,
"version": "0.0.0",
"devDependencies": {
"highlight.js": "^11.7.0",
"marked": "^4.2.12",
"ttypescript": "^1.5.15"
}
}

View File

@@ -0,0 +1,81 @@
const ts = require('typescript');
const path = require('path');
const fs = require('fs');
const marked = require('marked');
marked.setOptions({
headerIds: false,
highlight(code, lang) {
const highlightJs = require('highlight.js');
const language = highlightJs.getLanguage(lang) ? lang : 'plaintext';
return highlightJs.highlight(code, {language}).value;
},
});
marked.use({
renderer: {
link(href, title, text) {
return `<a href='${href}' target='_blank'>${text}</a>`;
},
},
});
const transformerProgram = program => context => sourceFile => {
const sourceMap = new Map();
const visitor = node => {
if (
(node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
ts.isStringLiteral(node)) &&
node.getFullText().trim().startsWith('// language=markdown')
) {
return ts.factory.createStringLiteral(marked.parse(node.text));
}
if (
ts.isImportDeclaration(node) &&
ts.isStringLiteral(node.moduleSpecifier) &&
node.importClause.name !== undefined
) {
/**
* @type {ts.TypeChecker}
*/
const typeChecker = program.getTypeChecker();
const moduleSymbol = typeChecker.getSymbolAtLocation(
node.moduleSpecifier,
);
if (moduleSymbol.escapedName !== '"*.md"') {
return node;
}
const baseDir = path.dirname(sourceFile.fileName);
const content = marked.parse(
fs.readFileSync(
path.resolve(baseDir, node.moduleSpecifier.text),
'utf-8',
),
);
const variableSymbol = typeChecker.getSymbolAtLocation(
node.importClause.name,
);
sourceMap.set(variableSymbol, content);
return undefined;
}
if (ts.isIdentifier(node)) {
const typeChecker = program.getTypeChecker();
const symbol = typeChecker.getSymbolAtLocation(node);
if (sourceMap.has(symbol)) {
return ts.factory.createStringLiteral(sourceMap.get(symbol));
}
return node;
}
return ts.visitEachChild(node, visitor, context);
};
return ts.visitNode(sourceFile, visitor);
};
module.exports = transformerProgram;

View File

@@ -0,0 +1,8 @@
module.exports = () => ({
name: 'markdown-literals',
async load(id) {
if (id.endsWith('.md')) {
return `export default 'Mockup text';`;
}
},
});

View File

@@ -10,6 +10,10 @@
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAOwAAADsAEnxA+tAAABKklEQVQ4jcWTvUoDURCFv/y0A2tnZ95AW7FZwQdQSO9aRLAJbp0mPkGCTSCBmPQW8Q1SuKTU4AvkEeQO2K6MuSFmN+pCCg9cLhdmzpwzh1tK05RdUN6p+yeCftKK+kmrW4SguvGaNc3PGGRUVEE18x4Dl9dlheP76OZxMQUCIOzVa++/W2jENYaV7oqEWTMETMmhv7fi+w4i4IVhxaaeAq+9es0aL4CJqoaqOsmSrGNsxCZ16ideMeiMVPVrJyISqerC7IhIsN3CoGMeTfYceKARn6/sqOozcADkktmMcU3y5KeZrQQ4ARxwpqpts5O3kIEvGvnJ1vwB7PuquYgc5RVs4tZHeAe8WbOIlIA9r3IJU/DXcc61nXOpcy7I1hb9C5aOLTeHf/6NwCdua48fJxuYPgAAAABJRU5ErkJggg=="
/>
<link rel="stylesheet" href="{{style}}" />
<link
rel="stylesheet"
href="https://unpkg.com/highlightjs@9.16.2/styles/atom-one-dark.css"
/>
<title>Motion Canvas</title>
</head>
<body>

View File

@@ -30,6 +30,7 @@
"@motion-canvas/core": "^12.1.0",
"@preact/preset-vite": "^2.3.0",
"clsx": "^1.2.1",
"highlight.js": "^11.7.0",
"preact": "10.7.3",
"source-map-js": "^1.0.2",
"typescript": "^4.6.4",

View File

@@ -9,6 +9,10 @@
sizes="16x16"
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAOwAAADsAEnxA+tAAABKklEQVQ4jcWTvUoDURCFv/y0A2tnZ95AW7FZwQdQSO9aRLAJbp0mPkGCTSCBmPQW8Q1SuKTU4AvkEeQO2K6MuSFmN+pCCg9cLhdmzpwzh1tK05RdUN6p+yeCftKK+kmrW4SguvGaNc3PGGRUVEE18x4Dl9dlheP76OZxMQUCIOzVa++/W2jENYaV7oqEWTMETMmhv7fi+w4i4IVhxaaeAq+9es0aL4CJqoaqOsmSrGNsxCZ16ideMeiMVPVrJyISqerC7IhIsN3CoGMeTfYceKARn6/sqOozcADkktmMcU3y5KeZrQQ4ARxwpqpts5O3kIEvGvnJ1vwB7PuquYgc5RVs4tZHeAe8WbOIlIA9r3IJU/DXcc61nXOpcy7I1hb9C5aOLTeHf/6NwCdua48fJxuYPgAAAABJRU5ErkJggg=="
/>
<link
rel="stylesheet"
href="https://unpkg.com/highlightjs@9.16.2/styles/atom-one-dark.css"
/>
<title>Motion Canvas</title>
</head>
<body>

View File

@@ -68,12 +68,8 @@ $colors: (
.section {
margin: 16px 8px 8px;
pre {
background-color: var(--surface-color);
border-radius: 4px;
padding: 8px;
margin: 8px -8px;
overflow-x: auto;
p {
margin: 8px 0;
}
code {
@@ -82,6 +78,18 @@ $colors: (
border-radius: 4px;
}
pre {
margin: 8px -8px;
overflow-x: auto;
background-color: var(--surface-color);
padding: 8px;
border-radius: 4px;
code {
padding: 0;
}
}
a {
color: var(--theme);
text-decoration: none;
@@ -93,6 +101,26 @@ $colors: (
}
}
.sourceCode {
position: relative;
}
.viewSource {
position: absolute;
top: 0;
right: -8px;
border-radius: 4px;
padding: 8px;
background-color: var(--surface-color);
opacity: 0;
transition: opacity 0.1s;
&:focus,
.sourceCode:hover & {
opacity: 1;
}
}
.entry {
font-size: 12px;
line-height: 20px;
@@ -105,8 +133,12 @@ $colors: (
.link {
font-size: 12px;
text-decoration: underline;
cursor: pointer;
color: inherit;
&:hover {
text-decoration: underline;
}
}
.navbar {

View File

@@ -7,6 +7,8 @@ import {
StackTraceEntry,
} from '../../utils';
import {IconButton} from '../controls';
import {OpenInNew} from '../icons';
export interface SourceFrameProps {
entry: StackTraceEntry;
}
@@ -18,21 +20,26 @@ export function SourceCodeFrame({entry}: SourceFrameProps) {
);
return (
<pre
className={styles.code}
onDblClick={async () => {
if (entry) {
await openFileInEditor(entry);
}
}}
onMouseDown={e => {
// Prevent selection when double-clicking.
if (e.detail > 1) {
e.preventDefault();
}
}}
>
{frame ?? 'Could not load the source code.'}
</pre>
<div className={styles.sourceCode}>
<pre>
<code
className="language-ts"
dangerouslySetInnerHTML={{
__html: frame ?? 'Could not load the source code.',
}}
/>
</pre>
<IconButton
title="Go to source"
className={styles.viewSource}
onClick={async () => {
if (entry) {
await openFileInEditor(entry);
}
}}
>
<OpenInNew />
</IconButton>
</div>
);
}

View File

@@ -18,12 +18,12 @@ export function StackTrace({entries}: StackTraceProps) {
{entry.isExternal ? (
`${entry.file}:${entry.line}:${entry.column}`
) : (
<span
<button
className={styles.link}
onClick={() => openFileInEditor(entry)}
>
{entry.file}:{entry.line}:{entry.column}
</span>
</button>
)}
)
</div>

View File

@@ -1,36 +1,15 @@
.iconCheckbox {
width: 24px;
height: 24px;
position: relative;
}
.iconInput {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
appearance: none;
}
.iconLabel {
width: 24px;
height: 24px;
display: block;
cursor: pointer;
color: rgba(255, 255, 255, 0.54);
&.main {
color: #fff;
}
.iconInput + &:hover {
color: #fff;
}
.iconInput:checked + & {
&.checked {
color: var(--theme);
&:hover {
color: var(--theme);
}
&.main {
color: #fff;
}
@@ -39,8 +18,6 @@
.iconButton {
-webkit-appearance: none;
width: 24px;
height: 24px;
display: block;
cursor: pointer;
border: 0;

View File

@@ -7,13 +7,19 @@ interface IconButtonProps {
title?: string;
onClick?: () => void;
children: ComponentChildren;
className?: string;
}
export function IconButton({children, onClick, title}: IconButtonProps) {
export function IconButton({
children,
onClick,
title,
className,
}: IconButtonProps) {
return (
<button
title={title}
className={clsx(styles.iconButton)}
className={clsx(styles.iconButton, className)}
type="button"
onClick={onClick}
>

View File

@@ -2,12 +2,12 @@ import styles from './Controls.module.scss';
import clsx from 'clsx';
import {ComponentChildren} from 'preact';
import {IconButton} from './IconButton';
interface IconCheckboxProps {
children: ComponentChildren;
titleOn?: string;
titleOff?: string;
id: string;
onChange?: (value: boolean) => void;
checked?: boolean;
main?: boolean;
@@ -17,29 +17,21 @@ export function IconCheckbox({
children,
titleOn,
titleOff,
id,
onChange,
checked = false,
main = false,
}: IconCheckboxProps) {
return (
<div className={styles.iconCheckbox}>
<label
title={titleOff && !checked ? titleOff : titleOn}
className={clsx(styles.iconLabel, main && styles.main)}
htmlFor={id}
>
<input
className={styles.iconInput}
type="checkbox"
id={id}
checked={checked}
onChange={event => {
onChange?.((event.target as HTMLInputElement).checked);
}}
/>
{children}
</label>
</div>
<IconButton
className={clsx(
styles.iconCheckbox,
main && styles.main,
checked && styles.checked,
)}
title={titleOff && !checked ? titleOff : titleOn}
onClick={() => onChange?.(!checked)}
>
{children}
</IconButton>
);
}

View File

@@ -9,11 +9,11 @@ export interface ToggleProps {
export function Toggle({open, onToggle}: ToggleProps) {
return (
<div
<button
className={clsx(styles.toggle, open && styles.open)}
onClick={() => onToggle(!open)}
>
<ChevronRight />
</div>
</button>
);
}

View File

@@ -0,0 +1,7 @@
export function OpenInNew() {
return (
<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z" />
</svg>
);
}

View File

@@ -4,6 +4,7 @@ export * from './Clear';
export * from './DragIndicator';
export * from './Locate';
export * from './MotionCanvas';
export * from './OpenInNew';
export * from './Pause';
export * from './PhotoCamera';
export * from './PlayArrow';

View File

@@ -71,7 +71,6 @@ export function PlaybackControls() {
onChange={speed => player.setSpeed(speed)}
/>
<IconCheckbox
id={'audio'}
titleOn="Mute audio"
titleOff="Unmute audio"
checked={!state.muted}
@@ -86,7 +85,6 @@ export function PlaybackControls() {
<SkipPrevious />
</IconButton>
<IconCheckbox
id={'play'}
main
titleOn="Play"
titleOff="Pause"
@@ -99,7 +97,6 @@ export function PlaybackControls() {
<SkipNext />
</IconButton>
<IconCheckbox
id={'loop'}
titleOn="Loop video"
checked={state.loop}
onChange={() => player.toggleLoop()}

View File

@@ -1,5 +1,6 @@
import {SourceMapConsumer} from 'source-map-js';
import {withLoader} from './withLoader';
import highlight from 'highlight.js';
const externalFileRegex = /^\/(@fs|@id|node_modules)\//;
const stackTraceRegex = navigator.userAgent.toLowerCase().includes('chrome')
@@ -100,13 +101,16 @@ export function getSourceCodeFrame(entry: StackTraceEntry): string | null {
return null;
}
const sourceLines = source.split('\n');
const {line, column} = entry;
const lastLine = line + 2;
const spacing = lastLine.toString().length;
const formatted = sourceLines
.slice(line - 1, lastLine)
.map((text, index) => `${line + index} | ${text}`);
const sourceLines = source.split('\n').slice(line - 1, lastLine);
const code = highlight
.highlight('typescript', sourceLines.join('\n'))
.value.split('\n');
const formatted = code.map((text, index) => `${line + index} | ${text}`);
formatted.splice(1, 0, `${' '.repeat(spacing)} | ${' '.repeat(column)}^`);
return formatted.join('\n');
}

View File

@@ -6,8 +6,8 @@
"author": "motion-canvas",
"license": "MIT",
"scripts": {
"build": "tsc",
"watch": "tsc -w"
"build": "ttsc",
"watch": "ttsc -w"
},
"publishConfig": {
"registry": "https://npm.pkg.github.com/motion-canvas"
@@ -23,6 +23,7 @@
"vite": "3.x"
},
"devDependencies": {
"@motion-canvas/internal": "0.0.0",
"@types/mime-types": "^2.1.1",
"typescript": "^4.7.4",
"vite": "^3.0.9"

View File

@@ -0,0 +1,8 @@
Use the `makeProject()` function instead:
```ts
import {makeProject} from '@motion-canvas/core';
export default makeProject({
// Configuration and scenes go here.
});
```

1
packages/vite-plugin/src/globals.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
/// <reference types="@motion-canvas/internal" />

View File

@@ -3,6 +3,7 @@ import path from 'path';
import fs from 'fs';
import {Readable} from 'stream';
import mime from 'mime-types';
import projectInstance from './__logs__/project-instance.md';
export interface MotionCanvasPluginConfig {
/**
@@ -194,7 +195,7 @@ export default ({
` config.name = '${name}';`,
` config.logger.warn({`,
` message: 'A project instance was exported instead of a project factory.',`,
` remarks: \`Use the <code>makeProject()</code> function instead:<pre>import {makeProject} from '@motion-canvas/core';\nexport default makeProject({\n // Configuration and scenes go here.\n});</pre>\`,`,
` remarks: \`${projectInstance}\`,`,
` stack: config.creationStack,`,
` });`,
` return config;`,

View File

@@ -8,7 +8,12 @@
"target": "es2021",
"moduleResolution": "node",
"declaration": true,
"allowSyntheticDefaultImports": true
"allowSyntheticDefaultImports": true,
"plugins": [
{
"transform": "@motion-canvas/internal/transformers/markdown-literals.js"
}
]
},
"include": ["src"]
}