3D旋转 + SVG路径动画

3D旋转 + SVG路径动画

注:涉及到图片的位置需要替换图片换成自己的路径

<template>
    <div>
        <!-- 封面 -->
        <div v-if="!iframeShow" class="faHomePage">
            <div class="faTitle">
                <span class="fa_title_style">驾驶舱</span>
            </div>
            <div class="fa_container">
                <div class="container">
                    <!-- 圆心 -->
                    <div class="circle"></div>

                    <!-- 旋转 -->
                    <div class="borther">
                        <div id="lopp2"></div>
                        <div ref="menu" v-for="(item, index) in items" class="ball ball2" @mouseover="onMouseGo(index)" @mouseout="onMouseMove(index)"
                             :style="getItemStyle(index)">
                            <div class="borther_div" @click="clickUp(index, item)">
                                <img :src="isMouseEnter ? getTitleImgUrl(item.id, 1) : getTitleImgUrl(item.id, 2)" />
                                <div class="borther_name">{{ item.name }}</div>
                            </div>
                        </div>
                    </div>

                    <!-- 底座 -->
                    <div class="fmdz"></div>
                </div>
            </div>
        </div>

        <!-- 内容 -->
        <div v-if="iframeShow" class="main_pageBox">
            <!--  大屏内容  -->
            <div v-if="iframeShow" class="detailPage" style="position: absolute; width: 100%; height: 100%">
                <component :is="curDetailPage"/>
                <div class="btnReturnToHome" @click="toHomePage"/>
            </div>
        </div>
    </div>
</template>

<script>
    // 引组件
    import jbxx from '@/scopes/project/jiLJYZT/modulePart/jbxxfxNew/jbxxfxNew'

    export default {
        // VUE命名
        name: 'page',
        // 声明组件
        components: {
            jbxx,
        },
        // 声明变量
        data() {
            return {
                components: [
                    {name: '菜单一', zjName: 'null', detailPage: 'jbxxfxNew',},
                ],
                iframeShow: false, // iframe页面展示
                curDetailPage: '',

                isMouseEnter: true,
                items: [
                    {id: 1, name: '菜单一', detailPage: 'jbxx', srcPath: "menu1@1x.png"},
                    {id: 2, name: '菜单二', detailPage: 'czxzjy', srcPath: "menu2@1x.png"},
                    {id: 3, name: '菜单三', detailPage: 'ncldlzy', srcPath: "menu3@1x.png"},
                    {id: 4, name: '菜单四', detailPage: 'jywczb', srcPath: "menu4@1x.png"},
                    {id: 5, name: '菜单五', detailPage: 'yeWBLQKJK', srcPath: "menu5@1x.png"},
                    {id: 6, name: '菜单六', detailPage: 'djsyry', srcPath: "menu6@1x.png"},
                ]
            }
        },
        watch: {

        },

        created() {

        },

        mounted() {
            this.$nextTick(() => {
                // this.init() // 数据初始化方法
            })
        },

        methods: {
           

            toHomePage() {
                faceConfig.resDataConfig.submitParameter = {
                    _modulePartId_: this.resourceId,
                }


                this.curDetailPage = this.components[0].detailPage
                this.iframeShow = false
            },

            onMouseGo(i) {
                this._i = i;
                this.$refs.menu.forEach(item => {
                    item.classList.add('active')
                })

                this.isMouseEnter = !this.isMouseEnter;
            },

            onMouseMove(i) {
                this.$refs.menu.forEach(item => {
                    item.classList.remove('active')
                })

                this.isMouseEnter = !this.isMouseEnter;
            },

            clickUp(index, item) {
                this.curDetailPage = item.detailPage;
                this.iframeShow = !this.iframeShow;
            },

            getTitleImgUrl(i, type) {
                if (type == 1) {
                    return require(`./img/menu${i}@1x.png`)
                }

                if (type == 2 && i == this._i + 1) {
                    return require(`./img/menu${i}@1s.png`)
                } else {
                    return require(`./img/menu${i}@1x.png`)
                }
            },

        // 暂时6个图片可以平均分,要是数量不一致,可以调整一下s的值 getItemStyle(index) { const s
= 3.4 return { animationDelay: '-' + (5 + index * s) + 's, -' + (0 + index * s) + 's, -' + (0 + index * s) + 's' } }, }, } </script> <style scoped type="text/less" lang="less"> //主页面样式 .faHomePage { width: 1920px; height: 1080px; position: absolute; background: url("./img/封面动态背景.gif") no-repeat; background-size: 100% 100%; margin: 0; padding: 0; .faTitle { width: 1920px; height: 1080px; position: absolute; background: url("./img/封面动态背景框.png") no-repeat; background-size: 100% 100%; margin: 0; padding: 0; //标题样式 .fa_title_style { font-size: 40px; font-weight: bold; //文字之间相隔间距 letter-spacing: 5px; background-image: -webkit-linear-gradient(bottom, white, #bce8f1); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: absolute; left: 850px; top: 15px; } } .fa_container { position: absolute; @keyframes animX{ 0% { left: 0px; } 100% { left: 200px; } } @keyframes animY{ 0% { top: 0px; } 100% { top: 300px; } } @keyframes scale { 0% { transform: scale(0.4); z-index: 0 } 50% { transform: scale(1); z-index: 3 } 100% { transform: scale(0.5); z-index: 0 } } .ball { width: 5px; height: 9px; border-radius: 50%; position: absolute; color:#fff; font-size:22px; display:flex; align-items:center; justify-content:center; background-size: 100% 100%; -webkit-background-size: 100% 100%; z-index: 3; animation-duration: 10s, 10s, 20s; animation-timing-function: cubic-bezier(0.36,0,0.64,1); animation-iteration-count: infinite; animation-direction: alternate; animation-name: animX, animY,scale; } #lopp { width: 500px; height: 300px; border: 2px solid #999; border-radius: 50%; position: absolute; left: 50px; top: 70px; } .active { animation-play-state: paused; } @keyframes anim2X{ 0% { left: 30px; } 100% { left: 700px; } } @keyframes anim2Y{ 0% { top: 50px; } 100% { top: 450px; } } .ball2 { z-index: 3; width: 88px; height: 88px; border-radius: 50%; position: absolute; color:#fff; font-size:22px; display:flex; align-items:center; justify-content:center; background-size: 100% 100%; -webkit-background-size: 100% 100%; animation-duration: 10s, 10s, 20s; animation-timing-function: cubic-bezier(0.36,0,0.64,1); animation-iteration-count: infinite; animation-direction: alternate; animation-name: anim2X, anim2Y,scale; cursor: pointer; } #lopp2 { width: 600px; height: 400px; border-radius: 50%; position: absolute; left: 100px; top: 100px; } .circle { position: absolute; top: -7rem; left: -4rem; min-width: 900px; min-height: 400px; background: url("./img/封面地图.gif") no-repeat center center; mix-blend-mode: screen; background-size: 100% auto; z-index: 3; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .container { position: relative; transform: rotateX(20deg); width: 800px; height: 800px; margin: 20rem 0 0 36rem; mix-blend-mode: screen; .borther_div { .borther_name { font-family: Source Han Sans; font-size: 20px; font-weight: bold; width: 12rem; padding: 0 2rem; margin-top: -5rem; text-align: center; font-variation-settings: "opsz" auto; font-feature-settings: "kern" on; background: linear-gradient(180deg, #C8DDEC 11%, #EFF5FC 50%, #EAF0F5 88%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; text-shadow: 0px 0px 8px #6788F3; } } } .fmdz { position: absolute; top: 0; left: 0; min-width: 800px; min-height: 800px; background: url("./img/封面底座.gif") no-repeat center center; mix-blend-mode: screen; background-size: 100% auto; z-index: 2; } } } .main_pageBox {     // 具体内容样式 } </style>

 

效果图:

 

posted @ 2025-07-03 10:16  慕容冰菡  阅读(14)  评论(0)    收藏  举报