Skip to content

Commit

Permalink
Add onlyCanvas option to the video exporter
Browse files Browse the repository at this point in the history
  • Loading branch information
baku89 committed Feb 20, 2024
1 parent e398ad4 commit a42e2ca
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 41 deletions.
8 changes: 6 additions & 2 deletions docs/components/Sandbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,14 @@ watch(
)
const keys = useMagicKeys()
const exportKey = keys.shift_cmd_e
whenever(exportKey, async () => {
whenever(keys.cmd_control_e, async () => {
const {exportVideo} = await import('./exportVideo')
exportVideo(code.value, true)
})
whenever(keys.shift_cmd_e, async () => {
const {exportVideo} = await import('./exportVideo')
exportVideo(code.value)
})
</script>
Expand Down
105 changes: 66 additions & 39 deletions docs/components/exportVideo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,32 @@ import saferEval from 'safer-eval'

import {createDrawFunction, setupEvalContextCreator} from './createDrawFunction'

export async function exportVideo(code: string) {
export async function exportVideo(code: string, onlyCanvas = false) {
console.info('Start rendering video onlyCanvas:', onlyCanvas)

const now = new Date()
const defaultBasename: string | null =
[now.getFullYear(), now.getMonth() + 1, now.getDate()]
.map(n => n.toString().padStart(2, '0'))
.join('-') +
'_' +
[now.getHours(), now.getMinutes()]
.map(n => n.toString().padStart(2, '0'))
.join('-')

const promptResult = prompt('Export settings', defaultBasename + ':2')

if (!promptResult) {
return
}

// Parse prompt result
const [basename, durationStr] = promptResult.split(':')
const filename = `Pave_${basename}.webm`
const duration = parseFloat(durationStr)
const frameCount = 50 * duration

// Load dependencies
const monaco = await import('monaco-editor')
const {default: domtoimage} = await import('dom-to-image-more')

Expand Down Expand Up @@ -37,52 +62,49 @@ export async function exportVideo(code: string) {

const frames: string[] = []

const duration = 2

const frameCount = 50 * duration

for (let i = 0; i < frameCount; i++) {
const time = i / frameCount

evalFn(time)

videoContext.clearRect(0, 0, 1920, 1080)
videoContext.fillStyle = 'white'
videoContext.fillRect(0, 0, 1920, 1080)
videoContext.fillStyle = 'black'

const codeImg = await renderCode(code, time)

const codeWidth = 1920 - 1080 - 40
const codeHeight = codeImg.height * (codeWidth / codeImg.width)
videoContext.drawImage(
codeImg,
1080,
(1080 - codeHeight) / 2,
codeWidth,
codeHeight
)

const canvasTop = 40
const canvasBottom = 1080 - 40
const canvasLeft = 40
const canvasRight = 1040

videoContext.strokeStyle = '#ccc'
videoContext.beginPath()
for (let i = 0; i <= 10; i++) {
videoContext.moveTo(canvasLeft + i * 100, canvasTop)
videoContext.lineTo(canvasLeft + i * 100, canvasBottom)
videoContext.moveTo(canvasLeft, canvasTop + i * 100)
videoContext.lineTo(canvasRight, canvasTop + i * 100)
if (!onlyCanvas) {
videoContext.clearRect(0, 0, 1920, 1080)
videoContext.fillStyle = 'white'
videoContext.fillRect(0, 0, 1920, 1080)
videoContext.fillStyle = 'black'

const codeImg = await renderCode(code, time)

const codeWidth = 1920 - 1080 - 40
const codeHeight = codeImg.height * (codeWidth / codeImg.width)
videoContext.drawImage(
codeImg,
1080,
(1080 - codeHeight) / 2,
codeWidth,
codeHeight
)

const canvasTop = 40
const canvasBottom = 1080 - 40
const canvasLeft = 40
const canvasRight = 1040

videoContext.strokeStyle = '#ccc'
videoContext.beginPath()
for (let i = 0; i <= 10; i++) {
videoContext.moveTo(canvasLeft + i * 100, canvasTop)
videoContext.lineTo(canvasLeft + i * 100, canvasBottom)
videoContext.moveTo(canvasLeft, canvasTop + i * 100)
videoContext.lineTo(canvasRight, canvasTop + i * 100)
}
videoContext.stroke()
}
videoContext.stroke()

evalFn(time)
videoContext.drawImage(canvas, 40, 40, 1000, 1000)

const frame = await new Promise<string>((resolve, reject) => {
videoCanvas.toBlob(blob => {
const targetCanvas = onlyCanvas ? canvas : videoCanvas
targetCanvas.toBlob(blob => {
if (blob) {
resolve(URL.createObjectURL(blob))
} else {
Expand Down Expand Up @@ -120,7 +142,12 @@ export async function exportVideo(code: string) {

capturer.stop()

capturer.save()
capturer.save(blob => {
const a = document.createElement('a')
a.href = URL.createObjectURL(blob)
a.download = filename
a.click()
})

async function renderCode(
code: string,
Expand Down

0 comments on commit a42e2ca

Please sign in to comment.