Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
1385e9d
chore: add package `@sciux/math`
sheepbox8646 Jun 12, 2025
c27bac9
chore: change package path name
sheepbox8646 Jun 12, 2025
4665bf1
Merge branch 'main' into feat/math
sheepbox8646 Jun 12, 2025
15c793d
ci: add tsconfig for each package
sheepbox8646 Jun 12, 2025
284afcc
feat: `<angle>`, and it's dependent components
sheepbox8646 Jun 13, 2025
b0653c1
feat: tex, data-point, tex-on-angle-mark
sheepbox8646 Jun 14, 2025
935c176
feat: line
sheepbox8646 Jun 14, 2025
1220767
Merge branch 'main' into feat/math
sheepbox8646 Jun 14, 2025
8273d1e
Merge branch 'main' into feat/math
sheepbox8646 Jun 14, 2025
bff91a3
feat: line and it's dependent comps
sheepbox8646 Jun 17, 2025
ddf3f24
feat: figure
sheepbox8646 Jun 17, 2025
abc5900
feat: circle
sheepbox8646 Jun 17, 2025
6cfbeae
Merge branch 'main' into feat/math
sheepbox8646 Jun 18, 2025
6ad88ab
feat(math): add color pallete support for math comps
sheepbox8646 Jun 18, 2025
8b04be7
feat: `<function>` & `<axis>` & `<plane>`
sheepbox8646 Jun 19, 2025
ecc7049
feat: plane grid
sheepbox8646 Jun 20, 2025
ba39351
Merge branch 'main' into feat/math
sheepbox8646 Jun 21, 2025
90d99e3
feat: function-creation animation
sheepbox8646 Jun 21, 2025
8d41070
ci: update dependencies
sheepbox8646 Jun 24, 2025
297db15
ci: update denpendencies
sheepbox8646 Jun 27, 2025
97f21ec
Merge branch 'main' into feat/math
sheepbox8646 Jul 2, 2025
1d6da08
feat: parametric
sheepbox8646 Jul 2, 2025
57714f6
feat: creation animatiom of line & angle & arc
sheepbox8646 Jul 4, 2025
8864ee1
feat: circle animation
sheepbox8646 Jul 4, 2025
e4a17f3
feat: point mark of angle
sheepbox8646 Jul 4, 2025
0426342
fix: angle src radius calculate
Jul 4, 2025
e73e4df
feat: Use right angle markers when the angle is right angle
Jul 4, 2025
c1edeb3
ci: update dependencies
sheepbox8646 Jul 4, 2025
3e4c0d0
feat: creation animation of axis, plane
sheepbox8646 Jul 5, 2025
9e52dc4
feat: add component `<mermaid>`
Jul 5, 2025
bce6fa8
feat: projection
sheepbox8646 Jul 5, 2025
a10b967
feat: vector
sheepbox8646 Jul 5, 2025
3848406
feat: add tools
sheepbox8646 Jul 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export default antfu(
{
rules: {
'unused-imports/no-unused-vars': 'warn',

},
},
)
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"prepare": "simple-git-hooks",
"preview": "pnpm vite ./test"
},
"dependencies": {
"mermaid": "^11.8.0"
},
"devDependencies": {
"@antfu/eslint-config": "catalog:",
"@antfu/ni": "catalog:",
Expand Down
109 changes: 91 additions & 18 deletions packages/math/src/angle/arc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { theme } from '@sciux/utils-theme'
import { type } from 'arktype'
import { defineComponent } from 'sciux-laplace'
import { defineAnimation, defineComponent } from 'sciux-laplace'
import { LineType } from '../shared'
import { describeArc } from '../utils/arc-path'
import { resolveDasharray } from '../utils/line'
Expand All @@ -24,26 +24,99 @@ export const arc = defineComponent<'arc', typeof T.infer, {
attrs: T,
defaults: {
value: '',
type: 'solid',
},
setup() {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
path.setAttribute('d', describeArc([context.x, context.y], (context.startSide ?? context.endSide) / 3, context.from, context.to))
path.setAttribute('stroke', theme.pallete('primary'))
path.setAttribute('fill', 'none')
path.setAttribute('stroke-dasharray', resolveDasharray(attrs.type.value))
const texElement = generateTexNode(attrs.value?.value)
const length = (context.startSide ?? context.endSide) / 3
const angle = context.from + (context.to - context.from) / 2
const position = [
length * Math.cos(angle * Math.PI / 180),
length * Math.sin(angle * Math.PI / 180),
]
const texContainer = document.createElementNS('http://www.w3.org/2000/svg', 'g')
texContainer.setAttribute('transform', `translate(${position[0]}, ${position[1]})`)
texContainer.append(texElement)
container.append(path, texContainer)
return container
container.id = 'canvas-angle-arc'
const angleValue = Math.abs((context.to - context.from + 360) % 360)
const isRightAngle = Math.abs(angleValue - 90) < 1e-2
if (isRightAngle) {
const length = Math.min(context.startSide ?? 0, context.endSide ?? 0) / 3
const radFrom = context.from * Math.PI / 180
const radTo = context.to * Math.PI / 180
const p1 = [length * Math.cos(radFrom), length * Math.sin(radFrom)]
const p2 = [length * Math.cos(radTo), length * Math.sin(radTo)]
const line1 = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line1.setAttribute('x1', '0')
line1.setAttribute('y1', '0')
line1.setAttribute('x2', p1[0].toString())
line1.setAttribute('y2', p1[1].toString())
line1.setAttribute('stroke', theme.pallete('primary'))
line1.setAttribute('stroke-width', '1')
line1.setAttribute('stroke-dasharray', resolveDasharray(attrs.type.value))
const line2 = document.createElementNS('http://www.w3.org/2000/svg', 'line')
line2.setAttribute('x1', '0')
line2.setAttribute('y1', '0')
line2.setAttribute('x2', p2[0].toString())
line2.setAttribute('y2', p2[1].toString())
line2.setAttribute('stroke', theme.pallete('primary'))
line2.setAttribute('stroke-width', '1')
line2.setAttribute('stroke-dasharray', resolveDasharray(attrs.type.value))
const l1 = [length * 0.6 * Math.cos(radFrom), length * 0.6 * Math.sin(radFrom)]
const l2 = [length * 0.6 * Math.cos(radTo), length * 0.6 * Math.sin(radTo)]
const l3 = [l1[0] + (l2[0]), l1[1] + (l2[1])]
const lPath = document.createElementNS('http://www.w3.org/2000/svg', 'path')
lPath.setAttribute('d', `M ${l1[0]} ${l1[1]} L ${l3[0]} ${l3[1]} L ${l2[0]} ${l2[1]}`)
lPath.setAttribute('stroke', theme.pallete('primary'))
lPath.setAttribute('fill', 'none')
lPath.setAttribute('stroke-width', '1')
lPath.setAttribute('stroke-dasharray', resolveDasharray(attrs.type.value))
const texElement = generateTexNode(attrs.value?.value)
const labelPos = [
(l1[0] + l2[0] + l3[0]) / 3,
(l1[1] + l2[1] + l3[1]) / 3,
]
const texContainer = document.createElementNS('http://www.w3.org/2000/svg', 'g')
texContainer.setAttribute('transform', `translate(${labelPos[0]}, ${labelPos[1]})`)
texContainer.append(texElement)
container.append(line1)
container.append(line2)
container.append(lPath)
container.append(texContainer)
return container
}
else {
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
path.id = 'angle-arc'
path.setAttribute('d', describeArc([0, 0], Math.min(context.startSide ?? 0, context.endSide ?? 0) / 3, context.from, context.to))
path.setAttribute('stroke', theme.pallete('primary'))
path.setAttribute('fill', 'none')
path.setAttribute('stroke-dasharray', resolveDasharray(attrs.type.value))
const texElement = generateTexNode(attrs.value?.value)
const length = Math.min(context.startSide ?? 0, context.endSide ?? 0) / 3
const angle = context.from + (context.to - context.from) / 2
const position = [
length * Math.cos(angle * Math.PI / 180),
length * Math.sin(angle * Math.PI / 180),
]
const texContainer = document.createElementNS('http://www.w3.org/2000/svg', 'g')
texContainer.setAttribute('transform', `translate(${position[0]}, ${position[1]})`)
texContainer.append(texElement)
container.append(path, texContainer)
return container
}
},
}
})

export const angleArcCreation = defineAnimation((node: Node, _, { context }: {
context: {
from: number
to: number
startSide: number
endSide: number
}
}) => {
const el = node as HTMLElement
if (el.id !== 'canvas-angle-arc')
return
const path = el.querySelector('#angle-arc') as SVGPathElement
return (progress) => {
if (progress > 1) {
return true
}
path.setAttribute('d', describeArc([0, 0], Math.min(context.startSide ?? 0, context.endSide ?? 0) / 3, context.from, context.from - (context.from - context.to) * progress))
return false
}
})
23 changes: 22 additions & 1 deletion packages/math/src/angle/bouding.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { theme } from '@sciux/utils-theme'
import { type } from 'arktype'
import { defineComponent } from 'sciux-laplace'
import { defineAnimation, defineComponent } from 'sciux-laplace'
import { LineType } from '../shared'
import { describeArc } from '../utils/arc-path'
import { resolveDasharray } from '../utils/line'
Expand Down Expand Up @@ -28,6 +28,7 @@ export const bounding = defineComponent<'bounding', typeof T.infer, {
},
setup() {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
container.id = 'canvas-bounding'
const pathString = describeArc([context.x, context.y], context.startSide ?? context.endSide, context.from, context.to)
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
path.setAttribute('d', pathString)
Expand All @@ -50,3 +51,23 @@ export const bounding = defineComponent<'bounding', typeof T.infer, {
},
}
})

export const boundingCreation = defineAnimation((node: Node, _, { context }: { context: {
x: number
y: number
from: number
to: number
startSide?: number
endSide: number
} }) => {
const el = node as HTMLElement
if (el.id !== 'canvas-bounding')
return
const path = el.querySelector('#canvas-bounding-path') as SVGPathElement
return (progress) => {
if (progress > 1)
return true
path.setAttribute('d', describeArc([0, 0], Math.min(context.startSide ?? 0, context.endSide ?? 0), context.from, context.from - (context.from - context.to) * progress))
return false
}
})
47 changes: 46 additions & 1 deletion packages/math/src/angle/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { theme } from '@sciux/utils-theme'
import { type } from 'arktype'
import { defineComponent } from 'sciux-laplace'
import { defineAnimation, defineComponent } from 'sciux-laplace'
import { LineType } from '../shared'
import { resolveDasharray } from '../utils/line'
import { generateTexNode } from '../utils/tex'
import { arc } from './arc'
import { bounding } from './bouding'
import { angleEndPoint, angleStartPoint, origin } from './points'
Expand Down Expand Up @@ -38,6 +39,7 @@ export const angle = defineComponent<'angle', typeof T.infer>((attrs) => {
},
setup(children) {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
container.id = 'canvas-angle'
container.setAttribute('transform', `translate(${attrs.x.value}, ${attrs.y.value})`)
const resolve = (value: number, length: number): { x1: number, y1: number, x2: number, y2: number } => {
const radian = value * Math.PI / 180
Expand All @@ -51,6 +53,7 @@ export const angle = defineComponent<'angle', typeof T.infer>((attrs) => {
const startSide = resolve(attrs.from.value, attrs.startSide.value)
const endSide = resolve(attrs.to.value, attrs.endSide.value)
const startSideLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')
startSideLine.id = 'angle-start-side'
startSideLine.setAttribute('x1', startSide.x1.toString())
startSideLine.setAttribute('y1', startSide.y1.toString())
startSideLine.setAttribute('x2', startSide.x2.toString())
Expand All @@ -60,13 +63,33 @@ export const angle = defineComponent<'angle', typeof T.infer>((attrs) => {
startSideLine.setAttribute('stroke-dasharray', resolveDasharray(attrs.startSideType.value))
container.append(startSideLine)
const endSideLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')
endSideLine.id = 'angle-end-side'
endSideLine.setAttribute('x1', endSide.x1.toString())
endSideLine.setAttribute('y1', endSide.y1.toString())
endSideLine.setAttribute('x2', endSide.x2.toString())
endSideLine.setAttribute('y2', endSide.y2.toString())
endSideLine.setAttribute('stroke', theme.pallete('primary'))
endSideLine.setAttribute('stroke-width', '1')
endSideLine.setAttribute('stroke-dasharray', resolveDasharray(attrs.endSideType.value))

const startSideTexPosition = [
startSide.x1 + (startSide.x2 - startSide.x1) / 2,
startSide.y1 + (startSide.y2 - startSide.y1) / 2,
]
const startSideTex = document.createElementNS('http://www.w3.org/2000/svg', 'g')
startSideTex.setAttribute('transform', `translate(${startSideTexPosition[0]}, ${startSideTexPosition[1]})`)
startSideTex.append(generateTexNode(attrs.startSideValue?.value ?? ''))
container.append(startSideTex)

const endSideTexPosition = [
endSide.x1 + (endSide.x2 - endSide.x1) / 2,
endSide.y1 + (endSide.y2 - endSide.y1) / 2,
]
const endSideTex = document.createElementNS('http://www.w3.org/2000/svg', 'g')
endSideTex.setAttribute('transform', `translate(${endSideTexPosition[0]}, ${endSideTexPosition[1]})`)
endSideTex.append(generateTexNode(attrs.endSideValue?.value ?? ''))
container.append(endSideTex)

container.append(endSideLine)
container.append(...children())
return container
Expand All @@ -82,3 +105,25 @@ export const angle = defineComponent<'angle', typeof T.infer>((attrs) => {
space,
}
})

export const angleCreation = defineAnimation((node: Node) => {
const el = node as HTMLElement
if (el.id !== 'canvas-angle')
return
const startSide = el.querySelector('#angle-start-side')
const endSide = el.querySelector('#angle-end-side')
const start = [Number(startSide?.getAttribute('x2')), Number(startSide?.getAttribute('y2'))]
const end = [Number(endSide?.getAttribute('x2')), Number(endSide?.getAttribute('y2'))]
return (progress) => {
if (progress > 1) {
return true
}
startSide?.setAttribute('x2', (start[0] * progress).toString())
startSide?.setAttribute('y2', (start[1] * progress).toString())
endSide?.setAttribute('x2', (end[0] * progress).toString())
endSide?.setAttribute('y2', (end[1] * progress).toString())
return false
}
})

export { angleArcCreation } from './arc'
48 changes: 40 additions & 8 deletions packages/math/src/angle/points.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import { defineComponent } from 'sciux-laplace'
import { InfoPointType } from '../shared'
import { generateTexNode } from '../utils/tex'

export const angleStartPoint = defineComponent<'start-point', typeof InfoPointType.infer, {
x: number
y: number
startSide: number
from: number
}>((attrs, context) => {
const position = [
context.startSide * Math.cos(context.from * Math.PI / 180) + context.x,
context.startSide * Math.sin(context.from * Math.PI / 180) + context.y,
]
return {
name: 'start-point',
attrs: InfoPointType,
globals: {
[attrs.as.value]: [
context.startSide * Math.cos(context.from * Math.PI / 180),
context.startSide * Math.sin(context.from * Math.PI / 180),
],
[attrs.as.value]: position,
},
defaults: {
value: '',
},
setup() {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
container.setAttribute('transform', `translate(${position[0] - context.x}, ${position[1] - context.y})`)
const texElement = generateTexNode(attrs.value.value)
container.append(texElement)
return container
},
}
})
Expand All @@ -25,14 +37,25 @@ export const angleEndPoint = defineComponent<'end-point', typeof InfoPointType.i
endSide: number
to: number
}>((attrs, context) => {
const position = [
context.endSide * Math.cos(context.to * Math.PI / 180) + context.x,
context.endSide * Math.sin(context.to * Math.PI / 180) + context.y,
]
return {
name: 'end-point',
attrs: InfoPointType,
globals: {
[attrs.as.value]: [
context.endSide * Math.cos(context.to * Math.PI / 180),
context.endSide * Math.sin(context.to * Math.PI / 180),
],
[attrs.as.value]: position,
},
defaults: {
value: '',
},
setup() {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
container.setAttribute('transform', `translate(${position[0] - context.x}, ${position[1] - context.y})`)
const texElement = generateTexNode(attrs.value.value)
container.append(texElement)
return container
},
}
})
Expand All @@ -47,5 +70,14 @@ export const origin = defineComponent<'origin', typeof InfoPointType.infer, {
globals: {
[attrs.as.value]: [context.x, context.y],
},
defaults: {
value: '',
},
setup() {
const container = document.createElementNS('http://www.w3.org/2000/svg', 'g')
const texElement = generateTexNode(attrs.value.value)
container.append(texElement)
return container
},
}
})
Loading
Loading