model-list.vue 7.08 KB
<template>
    <section class="model-list" v-show="isVisible">
        <Card :title="`${$t('files')}  (${sceneActiveMeshes.length})`" customClass="list">
            <template v-slot:component>
                <div class="content">
                    <div
                        v-for="(item, index) in sceneActiveMeshes"
                        :class="item.isSelected ? 'model selected' : 'model'"
                        :key="index"
                        @click.exact.stop="onClickModel(item.key)"
                        @click.ctrl.stop="onCtrlClickModel(item.key)"
                    >
                        <!-- 
                        <div class="extend">
                            <img :src="extendLeftIcon" alt="" />
                        </div>
                        -->
                        <div class="visible" @click.stop="onMeshVisible(item.key, !item.isVisible)">
                            <img :src="item.isVisible ? visibleIcon : invisibleIcon" alt="" />
                        </div>
                        <div class="name">
                            <el-tooltip
                                class="box-item"
                                effect="dark"
                                :content="item.name"
                                placement="top-start"
                                :show-after="600"
                                :hide-after="0"
                            >
                                <span>{{ item.name }}</span>
                            </el-tooltip>
                        </div>
                        <div class="opacity">
                            <el-slider
                                v-model="item.opacity"
                                :max="1"
                                :min="0"
                                :step="0.1"
                                @input="(val) => onOpacityChange(item.key, val)"
                            />
                        </div>
                        <!-- 
                        <div class="close" @click.stop="onMeshDelete(item.key)">
                            <img :src="closeIcon" alt="" />
                        </div>
                        -->
                    </div>
                </div>
            </template>
        </Card>
    </section>
</template>
<script setup>
import Card from '@/components/simple-card.vue';
import { useEditorStore } from '@/views/stores/useEditorStore';
import { watch, ref } from 'vue';
import { storeToRefs } from 'pinia';
import { visibleIcon, invisibleIcon, closeIcon, extendLeftIcon } from './icons';

const store = useEditorStore();
const { sceneActiveMeshes } = storeToRefs(store);
const { setMeshVisible, setMeshDelete, setMeshSelect, setMeshCtrlSelect, setMeshOpacity } = store;

const value1 = ref(0);
const isVisible = ref(true);
const itemWidth = ref('222px');

const onMeshVisible = (key, visible) => {
    setMeshVisible(key, visible);
};

const onMeshDelete = (key) => {
    setMeshDelete(key);
};

const onClickModel = (key) => {
    setMeshSelect(key);
};

const onCtrlClickModel = (key) => {
    setMeshCtrlSelect(key);
};

const onOpacityChange = (key, val) => {
    setMeshOpacity(key, val);
};

watch(
    () => sceneActiveMeshes.value.length,
    () => {
        itemWidth.value = sceneActiveMeshes.value.length > 5 ? '189px' : '194px';
        isVisible.value = true; //sceneActiveMeshes.value.length > 0;
    }
);
</script>
<style lang="less" scoped>
.list {
    width: unset !important;
    height: 184px !important;
}
.model-list {
    .content {
        display: flex;
        flex-direction: column;
        // width: 222px;
        // max-height: 180px;
        overflow: hidden auto;
        height: 150px;
        .model,
        .model.selected {
            width: v-bind('itemWidth');
            height: 30px;
            border-radius: 4px;
            // background-color: rgb(240, 241, 244);
            display: flex;
            -webkit-box-align: center;
            align-items: center;
            padding-left: 2px;
            margin-bottom: 2px;
            user-select: none;
            cursor: pointer;
            .extend {
                width: 24px;
                height: 100%;
                cursor: pointer;
                display: flex;
                user-select: none;
                img {
                    width: 18px;
                    height: 18px;
                    margin: auto;
                }
            }
            .visible {
                width: 24px;
                height: 100%;
                cursor: pointer;
                display: flex;
                user-select: none;
                img {
                    width: 18px;
                    height: 18px;
                    margin: auto;
                }
            }
            .name {
                width: 200px;
                height: 100%;
                font-size: 14px;
                font-weight: 500;
                letter-spacing: -0.1px;
                user-select: none;
                white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
                z-index: 2;
                pointer-events: none;
                span {
                    font-size: 14px;
                    font-weight: 500;
                    letter-spacing: -0.1px;
                    margin: 8px 0px 6px 6px;
                    user-select: none;
                    line-height: 28px;
                }
            }
            .opacity {
                position: fixed;
                width: 160px;
                margin-left: 25px;
                z-index: 1;
                :deep(.el-slider) {
                    .el-slider__runway {
                        height: 30px !important;
                        background-color: transparent !important;
                        .el-slider__bar {
                            height: 30px !important;
                            background-color: rgba(255, 81, 0, 0.1) !important;
                        }
                        .el-slider__button-wrapper {
                            top: -4px !important;
                        }
                        .el-slider__button-wrapper {
                            .el-slider__button {
                                width: 4px !important;
                                border-radius: 0% !important;
                                height: 30px !important;
                            }
                        }
                    }
                }
            }
            .close {
                width: 24px;
                height: 100%;
                cursor: pointer;
                display: flex;
                user-select: none;
                img {
                    width: 16px;
                    height: 16px;
                    margin: auto;
                    &:hover {
                        background-color: rgb(246, 247, 248);
                    }
                    &:active {
                        background-color: #eef0f2;
                    }
                }
            }
        }
        .model.selected {
            background-color: @main-modellist-selected-color;
        }
    }
}
</style>