| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <template>
- <div class="canvas-board-wrapper" :style="wrapperStyle">
- <div class="canvas-board" :style="canvasStyle">
- <slot />
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue';
- interface Props {
- width?: number | string;
- height?: number | string;
- bg?: string;
- scale?: number;
- }
- const props = defineProps<Props>();
- const canvasStyle = computed(() => {
- // console.log('props.bg', props.bg);
- let bgValue = props.bg;
- let imgUrl: string | undefined;
- // 尝试解析 bg 为数组并取 url
- if (typeof bgValue === 'string' && bgValue.trim().startsWith('[')) {
- try {
- const arr = JSON.parse(bgValue);
- if (Array.isArray(arr) && arr.length > 0 && arr[0].url) {
- imgUrl = arr[0].url;
- }
- } catch (e) {
- // 解析失败,忽略
- }
- }
- const isHex = typeof bgValue === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(bgValue);
- const isImg = typeof bgValue === 'string' && /^https?:\/\/.+\.(png|jpe?g|webp|gif|bmp|svg)(\?.*)?$/i.test(bgValue);
- if (isHex) {
- // console.log('Is Hex BG');
- return {
- width: '100%',
- height: '100%',
- background: props.bg,
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- fontSize: '20px',
- color: '#aaa',
- borderRadius: '12px',
- boxShadow: '0 2px 8px rgba(0,0,0,0.08)'
- };
- } else if (isImg) {
- // console.log('Is Img BG');
- return {
- width: '100%',
- height: '100%',
- backgroundImage: `url(${bgValue})`,
- backgroundSize: 'cover',
- backgroundPosition: 'center',
- backgroundRepeat: 'no-repeat',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- fontSize: '20px',
- color: '#aaa',
- borderRadius: '12px',
- boxShadow: '0 2px 8px rgba(0,0,0,0.08)'
- };
- } else if (imgUrl) {
- // console.log('Is Img BG (from array)');
- return {
- width: '100%',
- height: '100%',
- backgroundImage: `url(${imgUrl})`,
- backgroundSize: 'cover',
- backgroundPosition: 'center',
- backgroundRepeat: 'no-repeat',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- fontSize: '20px',
- color: '#aaa',
- borderRadius: '12px',
- boxShadow: '0 2px 8px rgba(0,0,0,0.08)'
- };
- } else {
- // console.log('Is Default BG');
- return {
- width: '100%',
- height: '100%',
- background: '#fff',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- fontSize: '20px',
- color: '#aaa',
- borderRadius: '12px',
- boxShadow: '0 2px 8px rgba(0,0,0,0.08)'
- };
- }
- });
- const wrapperStyle = computed(() => {
- const width = typeof props.width === 'number' ? props.width : parseFloat(props.width || '600');
- const height = typeof props.height === 'number' ? props.height : parseFloat(props.height || '400');
- const scale = props.scale && props.scale !== 1 ? props.scale : 1;
- return {
- width: width * scale + 'px',
- height: height * scale + 'px',
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- position: 'relative',
- overflow: 'hidden'
- };
- });
- </script>
- <style scoped>
- .canvas-board-wrapper {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- position: relative;
- overflow: hidden;
- }
- .canvas-board {
- transition: all 0.2s;
- }
- </style>
|