更新
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<view class="food-tile-icon" :class="[`food-tile-icon--${size}`]">
|
||||
<text class="food-tile-icon__emoji">{{ fallbackIcon }}</text>
|
||||
<image
|
||||
v-if="src && !imageFailed"
|
||||
class="food-tile-icon__img"
|
||||
:src="src"
|
||||
:mode="size === 'tile' ? 'aspectFill' : 'aspectFit'"
|
||||
@error="onImageError"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { getFoodImgUrl } from '../data/gameFoodImg.js'
|
||||
|
||||
const props = defineProps({
|
||||
food: { type: [Object, String], default: null },
|
||||
size: { type: String, default: 'tile' }
|
||||
})
|
||||
|
||||
const imageFailed = ref(false)
|
||||
|
||||
const fallbackIcon = computed(() => {
|
||||
if (typeof props.food === 'object' && props.food?.icon) return props.food.icon
|
||||
return '🍽'
|
||||
})
|
||||
|
||||
const src = computed(() => {
|
||||
if (typeof props.food === 'object' && props.food?.img) return props.food.img
|
||||
if (typeof props.food === 'object' && props.food?.icon) return getFoodImgUrl(props.food.icon)
|
||||
return ''
|
||||
})
|
||||
|
||||
watch(
|
||||
() => src.value,
|
||||
() => {
|
||||
imageFailed.value = false
|
||||
}
|
||||
)
|
||||
|
||||
function onImageError() {
|
||||
imageFailed.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.food-tile-icon {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.food-tile-icon--tile {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: calc(var(--tile-emoji-size, 48px) * 0.76);
|
||||
}
|
||||
|
||||
.food-tile-icon--tile .food-tile-icon__emoji,
|
||||
.food-tile-icon--tile .food-tile-icon__img {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.food-tile-icon--goal {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.food-tile-icon--tooltip {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.food-tile-icon__emoji {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: inherit;
|
||||
line-height: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.food-tile-icon--goal .food-tile-icon__emoji,
|
||||
.food-tile-icon--tooltip .food-tile-icon__emoji {
|
||||
position: static;
|
||||
transform: none;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.food-tile-icon__img {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user