Skip to content
This repository has been archived by the owner on Sep 8, 2024. It is now read-only.

Commit

Permalink
feat: add widget parameter support for json importing
Browse files Browse the repository at this point in the history
  • Loading branch information
sheepbox8646 committed Aug 16, 2024
1 parent 01d170c commit fa03b4c
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 130 deletions.
26 changes: 20 additions & 6 deletions examples/scene1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,26 @@ export default importScene(

`{
"root": {
"type": "MathFunction",
"arguments": ["fn((x) => Math.sin(x))", [-2, 2]],
"options": {
"x": "calc(200)",
"y": 100
}
"type": "Widget",
"children": [
{
"type": "MathFunction",
"arguments": [
"fn((x) => Math.sin(x))",
[-3.14, 3.14]
],
"options": {
"style": {
"color": [255, 0, 0, 1]
},
"lineWidth": 2,
"divisionY": 200,
"divisionX": 400,
"x": 100,
"y": 200
}
}
]
}
}
`,
Expand Down
8 changes: 8 additions & 0 deletions mods/mod-geometry/src/widgets/angle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Shader } from '@newcar/utils'
import { Color } from '@newcar/utils'
import type { FigureOptions, FigureStyle } from '@newcar/basic'
import { Arc, Line, Text } from '@newcar/basic'
import type { Canvas } from 'canvaskit-wasm'

export interface AngleOptions extends FigureOptions {
style?: AngleStyle
Expand Down Expand Up @@ -154,4 +155,11 @@ export class Angle extends Widget {

return { x: midX, y: midY }
}

draw(canvas: Canvas): void {
canvas.save()
canvas.scale(1, -1)
super.draw(canvas)
canvas.restore()
}
}
99 changes: 0 additions & 99 deletions packages/json/src/import-anim.ts

This file was deleted.

70 changes: 45 additions & 25 deletions packages/json/src/import-widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,70 @@ import { linear } from '@newcar/basic'
import type { WidgetFormat } from './format'
import { processAction } from './process-action'

export function processItem(color: string | Array<number>) {
if (Array.isArray(color)) {
return Color.rgba(color[0], color[1], color[2], color[3] ?? 1)
export function processItem(
item: string | Array<number> | WidgetFormat,
widgets: Record<string, typeof Widget>,
anims: Record<string, () => any>,
easingFunctions: Record<string, (t: number) => number>,
): any {
for (const key in widgets) {
if ((item as WidgetFormat).type === key) {
return importWidget(item as WidgetFormat, widgets, anims, easingFunctions)
}
}
else if (isString(color) && /color\(.+\)/.test(color)) {
return Color.parse(color.replace(/color\(/, '').replace(/\)$/, ''))
if (Array.isArray(item)) {
return Color.rgba(item[0], item[1], item[2], item[3] ?? 1)
}
else if (isString(color) && /shader\(.+\)/.test(color)) {
else if (isString(item as string) && /color\(.+\)/.test(item as string)) {
return Color.parse((item as string).replace(/color\(/, '').replace(/\)$/, ''))
}
else if (isString(item as string) && /shader\(.+\)/.test(item as string)) {
return Shader.createColorShader(Color.WHITE)
}
else if (isString(color) && /fn\(.+\)/.test(color)) {
else if (isString(item as string) && /fn\(.+\)/.test(item as string)) {
// eslint-disable-next-line no-new-func
return Function(`return ${color.replace(/fn\(/, '').replace(/\)$/, '')}`)()
return Function(`return ${(item as string).replace(/fn\(/, '').replace(/\)$/, '')}`)()
}
else if (isString(color) && /image\(.+\)/.test(color)) {
return useImage(color.replace(/image\(/, '').replace(/\)$/, ''))
else if (isString(item as string) && /image\(.+\)/.test(item as string)) {
return useImage((item as string).replace(/image\(/, '').replace(/\)$/, ''))
}
else if (isString(color) && /font\(.+\)/.test(color)) {
return useFont(color.replace(/font\(/, '').replace(/\)$/, ''))
else if (isString(item as string) && /font\(.+\)/.test(item as string)) {
return useFont((item as string).replace(/font\(/, '').replace(/\)$/, ''))
}
else if (isString(color) && /calc\(.+\)/.test(color)) {
else if (isString(item as string) && /calc\(.+\)/.test(item as string)) {
// eslint-disable-next-line no-new-func
return Function(`return ${color.replace(/calc\(/, '').replace(/\)$/, '')}`)()
return Function(`return ${(item as string).replace(/calc\(/, '').replace(/\)$/, '')}`)()
}
else {
return color
return item
}
}

export function processOptions(options: WidgetOptions) {
export function processOptions(
options: WidgetOptions,
widgets: Record<string, typeof Widget>,
anims: Record<string, () => any>,
easingFunctions: Record<string, (t: number) => number>,
) {
for (const key in options) {
if (typeof (options as Record<string, any>)[key] === 'object') {
(options as Record<string, any>)[key] = processOptions((options as Record<string, any>)[key])
(options as Record<string, any>)[key] = processOptions((options as Record<string, any>)[key], widgets, anims, easingFunctions)
}
(options as Record<string, any>)[key] = processItem((options as Record<string, any>)[key])
(options as Record<string, any>)[key] = processItem((options as Record<string, any>)[key], widgets, anims, easingFunctions)
}
return options
}

export function processArguments(args: unknown[]) {
export function processArguments(
args: unknown[],
widgets: Record<string, typeof Widget>,
anims: Record<string, () => any>,
easingFunctions: Record<string, (t: number) => number>,
) {
const result = []
for (const arg of args) {
if (isString(arg)) {
result.push(processItem(arg as string))
result.push(processItem(arg as string, widgets, anims, easingFunctions))
}
else {
result.push(arg)
Expand All @@ -67,7 +87,7 @@ export function importWidget<T extends typeof Widget>(
if (typeof widgetData === 'string') {
widgetData = JSON.parse(widgetData) as WidgetFormat
}
const widget = new widgets[widgetData.type](...processArguments(widgetData.arguments ?? []), processOptions(widgetData.options))
const widget = new widgets[widgetData.type](...processArguments(widgetData.arguments ?? [], widgets, anims, easingFunctions), processOptions(widgetData.options, widgets, anims, easingFunctions))
if (widgetData.children) {
widget.add(...widgetData.children.map((child) => {
return importWidget(child, widgets, anims, easingFunctions)
Expand All @@ -82,12 +102,12 @@ export function importWidget<T extends typeof Widget>(
? (ani.custom === 'change-property'
? changeProperty(() => (widget as Record<string, any>)[ani.target])
.withAttr({
...processOptions(ani.parameters),
...processOptions(ani.parameters, widgets, anims, easingFunctions),
by: easingFunctions[ani.parameters.by as string] ?? linear,
})
: console.warn(`[Newcar Warn] Json import error: there is no custom type named '${ani.custom}'`))
: anims[ani.type]().withAttr({
...processOptions(ani.parameters),
...processOptions(ani.parameters, widgets, anims, easingFunctions),
by: easingFunctions[ani.parameters.by as string] ?? linear,
})
})),
Expand All @@ -98,7 +118,7 @@ export function importWidget<T extends typeof Widget>(
if (animation.custom === 'change-property') {
widget.animate(changeProperty(() => (widget as Record<string, any>)[animation.target])
.withAttr({
...processOptions(animation.parameters),
...processOptions(animation.parameters, widgets, anims, easingFunctions),
by: easingFunctions[animation.parameters.by as string] ?? easingFunctions.linear,
}) as any)
}
Expand All @@ -108,7 +128,7 @@ export function importWidget<T extends typeof Widget>(
}
else {
widget.animate(anims[animation.type]().withAttr({
...processOptions(animation.parameters),
...processOptions(animation.parameters, widgets, anims, easingFunctions),
by: easingFunctions[animation.parameters.by as string] ?? easingFunctions.linear,
}))
}
Expand Down

0 comments on commit fa03b4c

Please sign in to comment.