feat: export video done
diff --git a/src/components/BBody.vue b/src/components/BBody.vue
index 1ad168f..d0d1638 100644
--- a/src/components/BBody.vue
+++ b/src/components/BBody.vue
@@ -1,80 +1,126 @@
 <template>
-    <div class="w-full h-full"
-        v-loading="isExportingVideo"
-        element-loading-text="视频生成中"
-    >
+    <div class="w-full h-full">
         <div class="grid grid-cols-12 h-full text-sm">
-            <el-card class="box-card col-span-3">
+            <el-card class="box-card col-span-3 scroll-card">
                 <h1 slot="header" class="clearfix text-xl">
                     {{$t('toolName')}}
                 </h1>
                 <div id="el-config" class="align-middle">
-                    <el-form ref="form">
-                        <div class="grid grid-cols-3 form-row">
-                            <label class="col-span-1">{{$t('chartTitle')}}</label>
-                            <el-input
-                                id="input-title"
-                                size="medium"
-                                class="col-span-2"
-                                v-model="title"
-                                @change="runChart"
-                            >
-                            </el-input>
-                        </div>
-                        <div class="grid grid-cols-3 form-row">
-                            <label class="col-span-1">显示排名上限</label>
-                            <el-input
-                                id="input-max"
-                                type="number"
-                                value=""
-                                size="medium"
-                                class="col-span-2"
-                                v-model="maxDataCnt"
-                                @change="runChart"
-                            >
-                            </el-input>
-                        </div>
-                        <div class="grid grid-cols-3 form-row">
-                            <label class="col-span-1">每行动画时长(毫秒)</label>
-                            <el-input
-                                id="input-animation-duration"
-                                type="number"
-                                value="5000"
-                                size="medium"
-                                class="col-span-2"
-                                v-model="animationDuration"
-                                @change="runChart"
-                            >
-                            </el-input>
-                        </div>
-                        <div class="grid grid-cols-3 form-row">
-                            <label class="col-span-1">视频宽度</label>
-                            <el-input
-                                type="number"
-                                size="medium"
-                                class="col-span-2"
-                                v-model="width"
-                            >
-                            </el-input>
-                        </div>
-                        <div class="grid grid-cols-3 form-row">
-                            <label class="col-span-1">视频高度</label>
-                            <el-input
-                                type="number"
-                                size="medium"
-                                class="col-span-2"
-                                v-model="height"
-                            >
-                            </el-input>
-                        </div>
-                        <el-form-item>
-                            <el-button @click="download" type="primary">下载代码</el-button>
-                            <el-button @click="downloadVideo">生成视频</el-button>
-                        </el-form-item>
+                    <el-form ref="form" :disabled="isExportingVideo">
+                        <h2>图表设置</h2>
+                        <el-row>
+                            <el-col :span="12">
+                                {{$t('chartTitle')}}
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    id="input-title"
+                                    size="medium"
+                                    class="col-span-1"
+                                    v-model="title"
+                                    @change="runChart"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-col :span="12">
+                                显示排名上限
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    id="input-max"
+                                    type="number"
+                                    value=""
+                                    size="medium"
+                                    class="col-span-2"
+                                    placeholder="为空则显示所有"
+                                    v-model="maxDataCnt"
+                                    @change="runChart"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-col :span="12">
+                                每行动画时长<span class="hint">(毫秒)</span>
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    id="input-animation-duration"
+                                    type="number"
+                                    value="5000"
+                                    size="medium"
+                                    class="col-span-2"
+                                    v-model="animationDuration"
+                                    @change="runChart"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-button @click="download" type="primary">
+                                <i class="el-icon-download"></i>
+                                下载代码
+                            </el-button>
+                        </el-row>
+
+                        <el-divider></el-divider>
+
+                        <h2>视频设置</h2>
+                        <el-row>
+                            <el-col :span="12">
+                                视频宽度
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    type="number"
+                                    size="medium"
+                                    class="col-span-2"
+                                    v-model="width"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-col :span="12">
+                                视频高度
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    type="number"
+                                    size="medium"
+                                    class="col-span-2"
+                                    v-model="height"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-col :span="12">
+                                视频帧率<span class="hint">(FPS)</span>
+                            </el-col>
+                            <el-col :span="12">
+                                <el-input
+                                    type="number"
+                                    size="medium"
+                                    class="col-span-2"
+                                    v-model="fps"
+                                >
+                                </el-input>
+                            </el-col>
+                        </el-row>
+                        <el-row>
+                            <el-button @click="downloadVideo">
+                                <i class="el-icon-video-camera"></i>
+                                生成视频
+                            </el-button>
+                        </el-row>
                     </el-form>
                 </div>
             </el-card>
             <el-card
+                v-if="!isExportingVideo"
                 class="box-card col-span-4 relative"
                 body-style="height: 100%"
             >
@@ -84,7 +130,8 @@
                 />
             </el-card>
             <el-card
-                class="box-card col-span-5 relative"
+                class="box-card relative"
+                :class="isExportingVideo ? 'col-span-9' : 'col-span-5'"
                 body-style="height: 100%"
             >
                 <BChart
@@ -116,6 +163,7 @@
             animationDuration: 3000,
             width: 1280,
             height: 720,
+            fps: 30,
             videoPercentage: 40,
             isExportingVideo: false
         }
@@ -158,16 +206,34 @@
         },
 
         async downloadVideo() {
-            // this.isExportingVideo = true;
-            const isSuccess = await (this.$refs.bchart as any).captureVideo(this.width, this.height);
-            // this.isExportingVideo = false;
-            if (!isSuccess) {
-                // this.$notify.error({
-                //     title: '导出失败!',
-                //     message: '建议使用最新版 Chrome 或 Firefox',
-                //     duration: 0,
-                //     position: 'bottom-left'
-                // });
+            if (!this.width || !this.height) {
+                this.$notify.error({
+                    title: '视频高度宽度错误!',
+                    message: '高度宽度不能为 0',
+                    duration: 0,
+                    position: 'bottom-left'
+                });
+                return;
+            }
+
+            this.isExportingVideo = true;
+            const isSuccess = await (this.$refs.bchart as any).captureVideo(this.width, this.height, this.fps);
+            this.isExportingVideo = false;
+            if (isSuccess) {
+                this.$notify({
+                    title: '导出成功!',
+                    type: 'success',
+                    duration: 3000,
+                    position: 'bottom-left'
+                });
+            }
+            else {
+                this.$notify.error({
+                    title: '导出失败!',
+                    message: '建议使用最新版 Chrome 或 Firefox',
+                    duration: 0,
+                    position: 'bottom-left'
+                });
             }
         }
     }
@@ -175,8 +241,37 @@
 </script>
 
 <style scoped>
+.scroll-card {
+    overflow-y: auto;
+}
+
+.el-col-12 {
+    place-self: center;
+}
+
+h1 {
+    margin-bottom: 15px;
+    font-weight: bold;
+}
+
+h2 {
+    margin-bottom: 15px;
+    font-size: 16px;
+    font-weight: bold;
+}
+
+.hint {
+    color: #999;
+    font-size: 12px;
+}
+
+.el-button i {
+    display: inline-block;
+    margin-right: 2px;
+}
+
 @layer utilities {
-    .form-row {
+    .el-row {
         @apply my-3;
 
         label {
diff --git a/src/components/BChart.vue b/src/components/BChart.vue
index c0f83a2..c0ab889 100644
--- a/src/components/BChart.vue
+++ b/src/components/BChart.vue
@@ -1,21 +1,21 @@
 <template>
     <div>
-        <div slot="header" class="clearfix text-base">
+        <div slot="header" class="clearfix text-base" v-if="!isExportingVideo">
             {{$t('preview')}}
             <a href="javascript:;" @click="run()">
                 <i class="el-icon-refresh"></i>
             </a>
         </div>
+        <div slot="header" class="clearfix text-base" v-if="isExportingVideo">
+            <i class="el-icon-loading"></i>
+            {{$t('exporting')}}
+        </div>
         <div
             id="bar-race-preview"
             ref="chart"
             class="absolute bottom-4 top-14 left-5 right-5 border"
-            :class="isHidden ? 'hidden' : ''"
         >
         </div>
-        <div id="chart-hint" v-if="isHidden">
-            视频生成中无法预览
-        </div>
     </div>
 </template>
 
@@ -50,7 +50,7 @@
     data() {
         return {
             timeoutHandlers: [],
-            isHidden: false
+            isExportingVideo: false
         };
     },
     watch: {
@@ -82,13 +82,28 @@
             }
         },
 
-        captureVideo(width?: number, height?: number): Promise<boolean> {
+        captureVideo(width: number, height: number, fps: number): Promise<boolean> {
             return new Promise(resolve => {
                 try {
-                    this.isHidden = true;
+                    this.isExportingVideo = true;
                     this.doResetChart(width, height);
-                    const canvas = chart.getDom().children[0].children[0] as HTMLCanvasElement;
-                    const recorder = canvasRecord(canvas);
+                    const container = chart.getDom();
+                    const canvas = container.children[0].children[0] as HTMLCanvasElement;
+                    if (container.clientHeight) {
+                        if (container.clientWidth / container.clientHeight > width / height) {
+                            canvas.style.height = container.clientHeight + 'px';
+                            canvas.style.width = container.clientHeight / height * width + 'px';
+                        }
+                        else {
+                            canvas.style.width = container.clientWidth + 'px';
+                            canvas.style.height = container.clientWidth / width * height + 'px';
+                        }
+                    }
+
+                    const recorder = canvasRecord(canvas, {
+                        frameRate: fps || 30,
+                        filename: this.title || this.$t('toolName')
+                    });
                     time = Date.now();
 
                     recorder.start();
@@ -103,16 +118,16 @@
                             hasError = true;
                         }
 
-                        this.isHidden = false;
+                        this.isExportingVideo = false;
                         setTimeout(() => {
                             this.run();
+                            resolve(!hasError);
                         });
-                        resolve(hasError);
                     });
                 }
                 catch (e) {
                     console.error(e);
-                    this.isHidden = false;
+                    this.isExportingVideo = false;
                     resolve(false);
                 }
             });
@@ -167,7 +182,9 @@
                 }],
                 grid: {
                     right: 60,
-                    bottom: 30
+                    bottom: 30,
+                    left: 20,
+                    containLabel: true
                 },
                 title: [{
                     text: (this.chartData as any)[headerLength][0],
diff --git a/src/components/BTable.vue b/src/components/BTable.vue
index 81a0c33..c3b883a 100644
--- a/src/components/BTable.vue
+++ b/src/components/BTable.vue
@@ -39,7 +39,7 @@
     data() {
         return {
             tableData: [
-                ['', 'blueberry', 'banana', 'kiwi', 'watermelon']
+                ['', 'blueberry', 'kiwi', 'banana', 'watermelon']
                     // @ts-ignore:
                     .map(name => name ? this.$i18n.t(name) : ''),
                 // @ts-ignore:
diff --git a/src/helper/template.ts b/src/helper/template.ts
index 6f89e3c..8f49db7 100644
--- a/src/helper/template.ts
+++ b/src/helper/template.ts
@@ -82,10 +82,12 @@
                 }],
                 grid: {
                     right: 60,
-                    bottom: 30
+                    bottom: 30,
+                    left: 20,
+                    containLabel: true
                 },
                 title: [{
-                    text: 'aaa',
+                    text: data[headerLength][0],
                     right: 20,
                     bottom: 15,
                     textStyle: {
@@ -118,6 +120,9 @@
                                 label: {
                                     valueAnimation: true
                                 }
+                            }],
+                            title: [{
+                                text: data[headerLength + i + 1][0]
                             }]
                         });
                         removeTimeoutHandlers(timeout);
diff --git a/src/i18n/en-US.ts b/src/i18n/en-US.ts
index 2e7deaf..fda190d 100644
--- a/src/i18n/en-US.ts
+++ b/src/i18n/en-US.ts
@@ -11,5 +11,6 @@
     banana: 'Banana',
     kiwi: 'Kiwi',
     watermelon: 'Watermelon',
-    preview: 'Preview'
+    preview: 'Preview',
+    exporting: 'The video is under exporting'
 };
diff --git a/src/i18n/zh-CN.ts b/src/i18n/zh-CN.ts
index 8837bda..af328e7 100644
--- a/src/i18n/zh-CN.ts
+++ b/src/i18n/zh-CN.ts
@@ -15,7 +15,8 @@
     banana: '香蕉',
     kiwi: '猕猴桃',
     watermelon: '西瓜',
-    preview: '预览'
+    preview: '预览',
+    exporting: '视频正在导出中'
 };
 
 export default langCn;
\ No newline at end of file