| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- <script setup lang="ts">
- import html2canvas from 'html2canvas'
- const simplicityList = import.meta.glob('./images/Simplicity/*.png')
- const affairsList = import.meta.glob('./images/affairs/*.png')
- interface Questionnaire {
- title: string
- desc: string
- }
- interface defaultData {
- //海报二维码
- qrCode: string
- //绑定
- modelValue: boolean
- //公司名称
- cardTitle: string
- //内容与描述
- questionnaire?: Questionnaire
- }
- const props = withDefaults(defineProps<defaultData>(), {
- qrCode: '',
- cardTitle: ''
- })
- const questionnaire = ref<Questionnaire>({
- title: '',
- desc: ''
- })
- function initializeQuestionnaire(qr: Questionnaire | undefined): Questionnaire {
- if (qr) {
- const copiedQr = JSON.parse(JSON.stringify(qr))
- return {
- title: copiedQr.title,
- desc: copiedQr.desc
- }
- } else {
- return {
- title: '',
- desc: ''
- }
- }
- }
- questionnaire.value = initializeQuestionnaire(props.questionnaire)
- const Simplicity = ref<any>(Object.keys(simplicityList).map(key => new URL(key, import.meta.url).href))
- const affairs = ref<any>(Object.keys(affairsList).map(key => new URL(key, import.meta.url).href))
- const WHITE_COLOR = '#FFFFFF'
- const BLACK_COLOR = '#000000'
- const emits = defineEmits(['update:modelValue'])
- const templateType = computed({
- get: () => props.modelValue,
- set: value => {
- emits('update:modelValue', value)
- }
- })
- const posterRef = ref<any>(null)
- const activeName = ref<Number>(1)
- const questionBg = ref<any>(Simplicity.value[0])
- const radio1 = ref<String>('居中')
- const color1 = ref(WHITE_COLOR)
- const color2 = ref(BLACK_COLOR)
- const saveimg = (item: string) => {
- activeName.value = 1
- questionBg.value = item
- }
- const submitForm = () => {
- html2canvas(posterRef.value).then(canvas => {
- let baseImg = canvas.toDataURL('image/png')
- let save = document.createElement('a')
- save.href = baseImg
- save.download = '分享海报'
- save.click()
- })
- }
- const resetForm = () => {
- templateType.value = false
- }
- const radioChange = (e: any) => {
- color1.value = e === '居中' ? WHITE_COLOR : BLACK_COLOR
- color2.value = color1.value
- }
- </script>
- <template>
- <el-dialog v-model="templateType" width="800px" title="分享海报">
- <el-tabs v-model="activeName" class="demo-tabs" style="border-bottom: 1px solid #e5e5e5">
- <el-tab-pane label="海报模版" :name="0">
- <div class="text-lg font-bold mb-4">简约</div>
- <div class="flex justify-between">
- <div class="relative template_img" v-for="(item, index) in Simplicity" :key="index">
- <img class="template_img" :src="item" />
- <div class="absolute add_img">
- <div class="template_img flex items-center justify-center">
- <el-button type="primary" @click="saveimg(item)">使用模版</el-button>
- </div>
- </div>
- </div>
- </div>
- <div class="text-lg font-bold mb-4 mt-4">商务</div>
- <div class="flex justify-between">
- <div class="relative template_img" v-for="(item, index) in affairs" :key="index">
- <img class="template_img" :src="item" />
- <div class="absolute add_img">
- <div class="template_img flex items-center justify-center">
- <el-button type="primary" @click="saveimg(item)">使用模版</el-button>
- </div>
- </div>
- </div>
- </div>
- </el-tab-pane>
- <el-tab-pane label="生成海报" :name="1">
- <div class="flex">
- <div ref="posterRef" class="flex items-center justify-center new_box">
- <div class="relative">
- <img :src="questionBg" class="relative_img" />
- <div v-if="radio1 == '底部'" class="absolute flex justify-center items-center top-3 right-3">
- <img class="w-20px h-20px mr-5px" src="/logo.png" alt="qrcode" />
- <div class="font-bold" style="color: white">{{ props.cardTitle }}</div>
- </div>
- <div v-if="radio1 == '底部'" class="absolute p-3 flex items-center bottom-0 w-full relative_bg">
- <img class="mr-3 relative_btm_img" :src="props.qrCode" />
- <div>
- <div class="text-s font-bold" :style="{ color: color1 }">{{ questionnaire.title }}</div>
- <div class="text-xs font-bold" :style="{ color: color2 }">{{ questionnaire.desc }}</div>
- </div>
- </div>
- <div v-else class="absolute p-3 top-0 w-full">
- <div class="text-xl font-bold text-center mb-7" :style="{ color: color1 }">
- {{ questionnaire.title }}
- </div>
- <div class="text-center mb-6">
- <img class="relative_cen_img" :src="props.qrCode" />
- </div>
- <div class="mb-3">
- <div class="text-s font-bold text-center" :style="{ color: color2 }">
- {{ questionnaire.desc }}
- </div>
- </div>
- <div class="flex justify-center items-center">
- <img class="w-20px h-20px mr-5px" src="/logo.png" alt="qrcode" />
- <div class="font-bold" style="color: white">{{ props.cardTitle }}</div>
- </div>
- </div>
- </div>
- </div>
- <div class="separate"></div>
- <div class="new_box">
- <div class="flex justify-between">
- <div class="text-text-base font-bold mb-4">海报标题</div>
- <div><el-color-picker v-model="color1" />{{ color1 }}</div>
- </div>
- <div class="mb-4 w-full">
- <el-input v-model="questionnaire.title" maxlength="20" show-word-limit class="w-full"></el-input>
- </div>
- <div class="flex justify-between">
- <div class="text-text-base font-bold mb-4">海报文本</div>
- <div><el-color-picker v-model="color2" />{{ color2 }}</div>
- </div>
- <div class="mb-4">
- <el-input
- v-model="questionnaire.desc"
- type="textarea"
- show-word-limit
- maxlength="80"
- :rows="4"
- ></el-input>
- </div>
- <div>
- <div class="text-text-base font-bold mb-4">二维码位置</div>
- </div>
- <div>
- <el-radio-group v-model="radio1" size="large" @change="radioChange">
- <el-radio-button label="居中" />
- <el-radio-button label="底部" />
- </el-radio-group>
- </div>
- </div>
- </div>
- </el-tab-pane>
- </el-tabs>
- <template #footer>
- <div class="flex justify-end w-full">
- <el-button size="default" @click="resetForm()">取消</el-button>
- <el-button size="default" type="primary" @click="submitForm()">保存下载</el-button>
- </div>
- </template>
- </el-dialog>
- </template>
- <style lang="scss" scoped>
- .template_img {
- width: 130px;
- height: 174px;
- border-radius: 10px;
- }
- .template_img:hover .add_img {
- display: block;
- }
- .add_img {
- background-color: #ffffff99;
- z-index: 999;
- top: 0px;
- display: none;
- }
- .separate {
- background-color: #e5e5e5;
- width: 1px;
- height: 454px;
- margin: 0 30px;
- }
- .new_box {
- width: 370px;
- height: 454px;
- }
- .relative_img {
- width: 310px;
- height: 406px;
- border-radius: 10px;
- }
- .relative_bg {
- background-color: #ffffff99;
- }
- .relative_btm_img {
- width: 80px;
- height: 80px;
- border-radius: 5px;
- }
- .relative_cen_img {
- width: 150px;
- height: 150px;
- border-radius: 5px;
- }
- </style>
|