Skip to content

Commit

Permalink
Refactor doc components
Browse files Browse the repository at this point in the history
  • Loading branch information
baku89 committed Feb 18, 2024
1 parent fd11266 commit 79fff96
Show file tree
Hide file tree
Showing 6 changed files with 370 additions and 189 deletions.
8 changes: 8 additions & 0 deletions docs/.vuepress/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,11 @@ td code {
padding-right: 0;
color: var(--c-text);
}

.sandbox .page-meta {
display: none;
}

.sandbox .theme-default-content {
max-width: unset;
}
29 changes: 19 additions & 10 deletions docs/components/Editor.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<template>
<MonacoEditor
ref="monaco"
class="Editor"
:theme="theme"
:value="code"
:options="options"
:style="{height: height + 'px'}"
@update:value="emit('update:code', $event)"
@editorWillMount="onEditorWillMount"
/>
<div class="Editor" :style="autoHeight ? {minHeight: height + 'px'} : {}">
<MonacoEditor
ref="monaco"
:theme="theme"
:value="code"
:options="options"
@update:value="emit('update:code', $event)"
@editorWillMount="onEditorWillMount"
/>
</div>
</template>

<script lang="ts" setup>
Expand All @@ -21,6 +21,7 @@ import {defineAsyncComponent, ref} from 'vue'
defineProps<{
code: string
autoHeight?: boolean
}>()
const emit = defineEmits<{
Expand Down Expand Up @@ -88,6 +89,14 @@ function onEditorWillMount(monaco: typeof import('monaco-editor')) {
</script>

<style lang="stylus">
.Editor
position relative
.monaco-editor-vue3
position absolute
inset 0
.monaco-editor, .monaco-editor-background,
.monaco-editor .inputarea.ime-input
background transparent !important
Expand Down
189 changes: 24 additions & 165 deletions docs/components/Example.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
<template>
<div class="Example">
<ClientOnly>
<Editor v-model:code="editingCode" />
</ClientOnly>
<div class="canvas-wrapper">
<canvas ref="canvas" class="canvas" />
</div>
</div>
</template>

<script lang="ts" setup>
import {pausableWatch, throttledWatch, useCssVar} from '@vueuse/core'
import {mat2d, scalar, vec2} from 'linearly'
import {Curve, type Path} from 'pave'
import saferEval from 'safer-eval'
import {onMounted, ref, watch} from 'vue'
import {pausableWatch} from '@vueuse/core'
import {ref, watch} from 'vue'
import Editor from './Editor.vue'
import PaveRenderer from './PaveRenderer.vue'
const props = defineProps<{
code: string
Expand All @@ -42,169 +29,41 @@ watch(
watcher.resume()
}
)
const canvas = ref<null | HTMLCanvasElement>(null)
const context = ref<null | CanvasRenderingContext2D>(null)
const brandColor = useCssVar('--c-brand')
onMounted(async () => {
context.value = canvas.value?.getContext('2d') ?? null
const {Path, Arc, CubicBezier} = await import('pave')
throttledWatch(
() => [editingCode.value, canvas.value, context.value] as const,
([code, canvas, context]) => {
if (!canvas || !context) return
const stroke = (path: Path, color = '', lineWidth = 1) => {
context.fillStyle = 'none'
context.strokeStyle = color || brandColor.value
context.lineCap = 'round'
context.lineWidth = lineWidth
Path.drawToCanvas(path, context)
context.stroke()
}
const fill = (path: Path, color = '') => {
context.strokeStyle = 'none'
context.fillStyle = color || brandColor.value
Path.drawToCanvas(path, context)
context.fill()
}
const dot = (point: vec2, color = '', size = 3) => {
context.strokeStyle = 'none'
context.fillStyle = color || brandColor.value
Path.drawToCanvas(Path.circle(point, size / 2), context)
context.fill()
}
const debug = (path: Path, color = '') => {
const lineWidth = 0.5
const vertexSize = 3
context.fillStyle = color || brandColor.value
context.strokeStyle = color || brandColor.value
context.lineCap = 'round'
context.lineWidth = lineWidth
for (const curve of path.curves) {
let isFirstVertex = true
for (const {start, point, command, args} of Curve.segments(curve)) {
context.lineWidth = lineWidth
// Draw the first vertex
if (isFirstVertex) {
Path.drawToCanvas(Path.circle(start, vertexSize), context)
context.stroke()
isFirstVertex = false
}
if (command === 'L') {
Path.drawToCanvas(Path.line(start, point), context)
} else if (command === 'C') {
const [control1, control2] = args
// Draw handles
context.setLineDash([2, 1])
Path.drawToCanvas(Path.line(start, control1), context)
context.stroke()
Path.drawToCanvas(Path.line(point, control2), context)
context.stroke()
context.setLineDash([])
let bezier = Path.moveTo(Path.empty, start)
bezier = Path.cubicBezierTo(bezier, control1, control2, point)
Path.drawToCanvas(bezier, context)
} else if (command === 'A') {
let arc = Path.moveTo(Path.empty, start)
arc = Path.arcTo(arc, ...args, point)
Path.drawToCanvas(arc, context)
}
context.lineWidth = lineWidth
context.stroke()
context.lineWidth = vertexSize
Path.drawToCanvas(Path.dot(point), context)
context.stroke()
context.font = '7px "IBM Plex Mono"'
context.fillText(command[0], ...vec2.add(point, [2, -2]))
}
}
}
const {width, height} = canvas.getBoundingClientRect()
const dpi = window.devicePixelRatio
canvas.width = width * dpi
canvas.height = height * dpi
const scale = (width * dpi) / 100
context.clearRect(0, 0, canvas.width, canvas.height)
context.resetTransform()
context.transform(...mat2d.fromScaling([scale, scale]))
try {
saferEval(`(() => {\n${code}\n})()`, {
context,
Path,
Arc,
CubicBezier,
scalar,
vec2,
mat2d,
stroke,
fill,
dot,
debug,
})
} catch (e) {
// eslint-disable-next-line no-console
console.error(e)
}
},
{immediate: true, throttle: 100}
)
})
</script>

<template>
<ClientOnly>
<div class="Example">
<Editor v-model:code="editingCode" class="editor" :autoHeight="true" />
<PaveRenderer :code="code" class="renderer" />
</div>
</ClientOnly>
</template>

<style lang="stylus" scoped>
.Example
position relative
border 1px solid var(--c-border-dark)
padding 1em
border-radius var(--border-radius)
font-family var(--font-family-code)
min-height 200px
display grid
grid-template-columns 1fr 200px
overflow hidden
gap 1em 0
@media (max-width: 800px)
grid-template-columns 1fr
@media (max-width: 419px)
margin 0.85rem -1.5rem
border-radius 0
border-width 1px 0
.canvas-wrapper
.editor
width 100% !important
.renderer
width 200px
position absolute
top 1em
right 1em
height 200px
@media (max-width: 800px)
position relative
margin 0 auto 1em
.canvas
position absolute
inset 0
width 100%
height 100%
border-color var(--c-bg-light)
background var(--c-bg)
border-style solid
border-width 1px 1px 0 0
background-image: linear-gradient(0deg, var(--c-bg-light) 1px, transparent 1px),
linear-gradient(90deg, var(--c-bg-light) 1px, transparent 1px);
background-size: 10% 10%;
margin 0 auto
</style>
Loading

0 comments on commit 79fff96

Please sign in to comment.