记录--用 Vue 实现原神官网的角色切换效果

这篇具有很好参考价值的文章主要介绍了记录--用 Vue 实现原神官网的角色切换效果。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--用 Vue 实现原神官网的角色切换效果

前言

为了更好的了解原神角色,我模仿官网做了一个角色切换效果,在做的过程当中也总结了一些技术点。

为了让大家更好的体验,我兼容了 PC 端和移动端,建议在 PC 端查看效果更佳。接下来就为大家简单的分享一下!

话不多说,原神启动!!

效果

先看一下官网的效果: ys.mihoyo.com/main/charac…

我写的真实效果:chenyajun.fun/#/ysRoleSwi…

技术点

一、底部角色横向滚动效果

1、原理

记录--用 Vue 实现原神官网的角色切换效果

外层容器:就是底部角色可视窗口。

内层容器: 用来存放角色头像,点击左右键或者角色需要滚动的容器。

滚动元素: 就是我们看到的一个个角色头像。

首先我们使用外层容器来包裹所有的角色信息,同时使外层容器overflow:hidden。

其次我们通过点击左右按键或者任意角色来确定当前所处的 index。

最后通过固定角色宽度 ✖ index 来控制内层容器的left值,从而移动内层容器位置,最终显示当前激活的角色头像。(注:移动端实现效果不同,下面单独讲解) 

2、要求

记录--用 Vue 实现原神官网的角色切换效果

 

要求1:如果处于最左(右)侧的位置,点击左右键或者前三个角色头像不进行位移移动,只显示角色切换激活状态。

要求2:处于最左侧并且点击左键需要角色容器第一个为倒数第六个,也就是最后一栏。相反,处于最右侧并且点击右键需要移动到第一个,也就是第一栏。

要求3:点击中间部分永远保持在角色容器的第三个激活状态。

3、代码实现

大家可以根据HTML结构去理解代码

      <div class="role-outer" :style="{ width: isPC ? '830px' : '320px' }">
        <template>
          <div class="left-arrow" :style="{ backgroundImage: `url(${leftSwitchArrow})` }" @click="lastPage"></div>
          <div class="right-arrow" :style="{ backgroundImage: `url(${rightSwitchArrow})` }" @click="nextPage"></div>
        </template>

        <div class="role-contener">
           //内部容器
          <div
            class="role-inner"
            :class="{ activeTranstion: isCloseTranstion }"
            :style="{ left: isPC ? moveDistancePC : moveDistanceMobile }"
            ref="element"
          >
            //角色
            <template>
              <div
                v-for="(item, index) in yuRoleMes"
                class="role-item-pc"
                :style="{
                  backgroundPosition: $index === index ? '0 -132px' : '',
                  backgroundImage: `url(${bottomRoleBac})`,
                }"
                :key="index"
                @click="handleRoleSwitchPC(index)"
              >
                <img class="item-avater" :src="item.roleAvatar" />
                <p class="item-name" :style="{ color: $index === index ? '#000' : '#fff' }">{{ item.roleName }}</p>
              </div>
            </template>
          </div>
        </div>
      </div>
   </div>

可以看到我们通过 moveDistancePC 变量来控制内层容器的移动位移,接下来主要分析一下怎么控制 moveDistancePC !

1.点击操作

通过点击上一页、下一页以及角色信息来改变索引 $index。

// 上一页
function lastPage() {
  if ($index.value === 0) {
    $index.value = yuRoleMes.value.length - 1
    return
  }
  $index.value--
}
// 下一页
function nextPage() {
  // 到最后一页
  if ($index.value === yuRoleMes.value.length - 1) {
    $index.value = 0
    return
  }
  $index.value++
}
// 点击角色操作
function handleRoleSwitchPC(index) {
  isCloseTranstion.value = false
  $index.value = index
}

当处于第一个并且点击左键时,直接将索引赋值为最后一个角色。

  if ($index.value === 0) {
    $index.value = yuRoleMes.value.length - 1
    return
  }

当处于最后一个并且点击右键时,直接将索引赋值为0到第一个。

  // 到最后一页
  if ($index.value === yuRoleMes.value.length - 1) {
    $index.value = 0
    return
  }

2.索引控制移动位移

通过索引*角色宽度来进行位置的移动,不过需要进行界限判断,144为宽度(110px)+margin-right(34px)。

// 每次点击移动距离
const moveDistance = computed(() => {

    const firstThree = $index.value < 3
    if (firstThree) {
      return 0
    }

    const lastThree = $index.value > yuRoleMes.value.length - 4
    if (!lastThree) {
      return ($index.value - 2) * -144
    }

    return (yuRoleMes.value.length - 6) * -144
})

//对容器进行位移赋值
const moveDistancePC = computed(() => {
  return moveDistance.value + 'px'
})

情况一:

如果$index处于前三个,那么位置不变永远为0。

    const firstThree = $index.value < 3
    if (firstThree) {
      return 0
    }

情况二:

如果$index处于中间部分,永远保持为当前的第三个激活即可。

($index.value - 2) 意思为如果直接取 $index 那么角色位置会在第一个,保持在第三个就往后面移动两位,故减去两个即可。

    const lastThree = $index.value > yuRoleMes.value.length - 4
    if (!lastThree) {
      return ($index.value - 2) * -145
    }

情况三: 

如果$index处于后三个,那么位置不变,永远处于倒数第六个。

 return (yuRoleMes.value.length - 6) * -145

二、背景图片放大缩小切换效果

我们可以看到每个场景下会有两张背景图片在不断的切换,第一张结束之后第二张出现,两张图片循环播放,若隐若现。

代码实现

这一部分是直接模仿的官方的样式,直接说一下实现原理!

HTML

    <!-- 背景-两张切换 -->
    <div class="background-wrapper">
      <!-- 第一张背景 -->
      <div
        class="role-background role-bg1"
        :style="{
          backgroundImage: outerTwoBackground[0],
        }"
      ></div>
      <!-- 第二张背景 -->
      <div
        class="role-background role-bg2"
        :style="{
          backgroundImage: outerTwoBackground[1],
        }"
      ></div>
    </div>

需要使第一张背景永远处于存在且向外扩大的状态,通过关键帧动画控制第二张的显示隐藏,从而就达到了两张照片的交替显示隐藏,是不是很巧妙?

相关css代码:

// 第一张永远存在进行扩张
.role-bg1 {
  animation: breath 80s infinite linear;
  opacity: 1;
}
// 第二张也在扩张,只不过每次从显示到隐藏需要15秒
.role-bg2 {
  animation: bg-change 15s infinite linear, breath 80s infinite linear;
  opacity: 0;
}
// 用于第二张的显示隐藏
@keyframes bg-change {
  48% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  98% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}
// 用于向外扩张效果
@keyframes breath {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.2);
  }

  100% {
    transform: scale(1);
  }
}

三、背景角色切换效果

 

记录--用 Vue 实现原神官网的角色切换效果

到我们在切换角色的时候,第一个角色会移出,同时下一张照片会移入,并且伴有动画,这个效果也是css实现的。

1、原理

我们将所有的图片起初都定位到外面,默认显示第一张,而当我们切换照片时,我们设置需要显示的照片的 right 值,同时设置透明度,在这个过程中增加过渡动画即可。 ​

 2、实现代码

HTML结构

        <!-- 角色背景 -->
        <div class="role-wrapper">
          <div class="role-box">
            <img
              v-for="(item, index) in yuRoleMes"
              class="role-picture"
              :class="[index === $index ? show-background-pc' : 'hide-background']"
              :key="index"
              :src="item.roleBackground"
            />
          </div>
        </div>

我设置了两个类show-background-pc,hide-background前者用来显示切换的照片,index === $index时显示点击的照片,否则调整right值直接隐藏,两个都加上过渡动画,这样显示隐藏都会有效果了。

        .show-background-pc {
          right: 0;
          opacity: 1;
          transition: all 0.3s;
        }
        .show-background-mobile {
          right: 445px;
          opacity: 1;
          transition: all 0.3s;
        }

移动端

 1、底部角色滑动效果

记录--用 Vue 实现原神官网的角色切换效果

2、点击和触摸移动事件冲突

我在做的过程中发现点击事件和触摸事件发生了冲突,就是我既要滑动这个容器又要进行点击。

我采取的办法是结束位置减去起始位置是否为0,如果为0则视为点击事件!

  moveDistanceX.value = endX.value - startX.value
  // 如果是点击滑动
  if (moveDistanceX.value === 0) {
    isClickMobile(e)
    return
  }

如果为true则处理点击事件,否则处理移动事件即可,如果是点击事件的话,逻辑和 PC 相似,这里不再重复讲解,主要说一下滑动移动。

3、触摸移动角色容器

我们在触摸滑动容器时,容器需要跟着一起滑动

这里有一些变量,大家可能需要看一下

const isCloseTranstion = ref(false) //控制是否显示动画效果
const startX = ref(0) //记录开始位置
const endX = ref(0) //记录结束位置
const moveDistanceX = ref(0) //按下抬起滑动距离
const recordLastMove = ref(0) //记录上次滑动的距离,用于下次累加
const moveDistanceM = ref(0) //最终移动的距离

1.开始触摸

// 触摸开始
function handleTouchStart(e) {
  isCloseTranstion.value = true // 开始移动 关闭动画
  startX.value = e.touches[0].pageX || e.changedTouches[0].pageX
}

2.触摸移动

触摸移动的话,下面的容器需要实时跟着一起移动,也就是我们移动的位移需要实时的赋值上去,并且要累加上上次的位置,比如第一次移动到10,下次移动就是从10的基础上进行移动。

 //最终移动的距离赋值为容器left值即可
const moveDistanceMobile = computed(() => {
  return moveDistanceM.value + 'px'
})
// 触摸移动
function handleTouchMove(e) {
  e.preventDefault()
  isCloseTranstion.value = true // 开始移动 关闭动画
  moveDistanceX.value = (e.changedTouches[0].pageX || e.touches[0].pageX) - startX.value // 计算移动距离
  moveDistanceM.value = recordLastMove.value + moveDistanceX.value
}

3.触摸抬起

容器的最终位置这里就需要分情况进行处理了,满足相应的条件处理相应的逻辑即可。

情况一:

如果只有一栏照片或者直接往右边移动,那就只进行实时同步移动,只不过移动结束还恢复到原来位置即可。

  // 如果照片小于五张不进行位移移动
  if (yuRoleMes.value.length < 5) {
    moveDistanceM.value = 0
    recordLastMove.value = 0
    return
  }

情况二:

已经滑到最后一栏继续左滑,这时已经超出了最大界限,将最终位置定格在最大界限的位置

  // 最后一栏的位置
  const rightMaxValue = (yuRoleMes.value.length - 5) * -64  
//在最后一栏继续往左边滑动
  if (moveDistanceM.value < rightMaxValue) {
    moveDistanceM.value = rightMaxValue
    recordLastMove.value = rightMaxValue
    return
  }

情况三:

除了以上情况,也就是在中间正常滑动,我们进行赋值即可,使用 Math.round 来保证我们移动的都是每个角色的整数倍即可。

  // 其他情况
  moveDistanceM.value = recordLastMove.value + Math.round(moveDistanceX.value / 64) * 64
  recordLastMove.value = Math.round(moveDistanceM.value / 64) * 64

总结

声明:以上所有信息材料均来之于原神官网ys.mihoyo.com/main/charac…

上面我将功能进行了分开描述,PC 端和移动端最终效果不一样,所以代码实现也不一样,但其实实现逻辑相似,只不过需要对不同的情况进行处理。

另外就是每个情况需要考虑细致,我在写的过程中,总会有落下的问题,也就是测试用例不太全面,如果大家有发现不对的地方,可以在下方进行留言,我看到会进行及时更改的。

写作不易,你的赞就是我最大的动力,觉得写的不错的,可以给点个赞呢~

源码:

全部源码已经同步上传到了 GitHub

觉得写的不错了,可以给作者点一下star⭐

GitHub:chenyajun-create/ysRoleSwitch (github.com)

本文转载于:

https://juejin.cn/post/7277802797474021410

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--用 Vue 实现原神官网的角色切换效果文章来源地址https://www.toymoban.com/news/detail-708336.html

到了这里,关于记录--用 Vue 实现原神官网的角色切换效果的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue 实现钉钉官网的轮播图下面功能滚动排版CSS效果

    前言 最近在写PC端的业主端时候,发现传统的菜单栏比较丑,也不符合实际应用(功能页面并不多-展示为主) 偶然发现钉钉官网的效果挺有意思的,想着把这个效果复原过来,然后夸夸搜索了一番。 经过一顿的cv打法,加上修修补补把大概的效果整了出来,时间关系最基础

    2024年02月11日
    浏览(49)
  • 原神角色渲染详解

      整体效果展示:主要方案是对下面几张图做不同的处理 身体 基础颜色光照:主要贴图+卡通贴图+ramp图+法线图+光照图 金属度与高光,头发部分高光:光照图,头发部分用高光black图 深度边缘光:用额外pass DepthNormals 获取深度信息  描边:额外pass对描边进行处理,用光照图

    2023年04月08日
    浏览(75)
  • (3)原神角色数据分析-3

            在名为“WRITEPHOT.py”的文件中,定义如下绘图方式,则在主页面(app.py)文件中,可通过如下方式调用: 代码如下:

    2024年02月13日
    浏览(44)
  • werkzeug源码分析——从官网的示例代码开始

    全文基于Python 2.7 macOS 10.12.2 werkzeug是Python实现的WSGI规范的使用函数库。什么是WSGI?如何理解CGI,WSGI 网上的说明很多,在文章的开始,我想要强调两点 WSGI是一种服务器和客户端交互的接口规范 理解web组件:client, server, and middleware. 正如werkzeug官网Werkzeug上所说,werkzeug使用起

    2024年02月08日
    浏览(39)
  • 将原神角色导入unity 完整版

             首先需要获取角色模型,获取方式可以从原神官网获取,这里采用从模之屋进行获取,进入模之屋后搜索自己想要的角色,然后下载压缩包并解压。         模之屋:专业模型创作分享社区_模之屋_PlayBox         打开文件夹里的Pmx文件是我们需要进行转换的文件,

    2023年04月24日
    浏览(73)
  • 原神角色数据分析项目说明文档

    前端html语言,flask框架,excel,MySQL,DataFrame数组,numpy,pyecharts         将所有角色数据存储在excel表格中,在需要时读取,当用户想要查看某一项时,form提交相应的网址,在“app.py”文件中,找到该网址对应的函数,执行对应函数,将函数返回值(通常为.html文件)呈现。

    2024年02月10日
    浏览(39)
  • 通过官网的例子来学习ws-discovery

    ws-discovery该例子来自于ws-discovery.pdf,连接如下,表1和表2是对该例子的解释进行翻译,表3个是一个onvif的搜索响应 WS-Discovery (xmlsoap.org) ProbeMatches 消息 - Win32 apps | Microsoft Learn(microsoft的中文文档) (01) s:Envelope  (02) xmlns:a=\\\"http://schemas.xmlsoap.org/ws/2004/08/addressing\\\"  (03) xmlns:d=\\\"http://

    2024年02月11日
    浏览(32)
  • 单元测试gtest的安装与使用方法【结合官网的sample】

    gtest单元测试是Google的一套用于编写 C++测试的框架 ,可以运行在很多平台上(包括Linux、Mac OS X、Windows、Cygwin等等)。基于xUnit架构。支持很多好用的特性,包括自动识别测试、丰富的断言、断言自定义、死亡测试、非终止的失败、生成XML报告等等。 好的测试应该有下面的这

    2024年02月10日
    浏览(37)
  • 原神3D卡通动漫二次元角色模型Blender已绑骨骼

    3Dmax/C4D这类软件应该做三维的都知道。Blender知道的应该不多。一款跨平台开源的 3D 创作软件,可以在 Linux、macOS 以及 Windows 系统下运行。与其他 3D 建模工具相比,Blender 对内存和驱动的需求更低。 今天给大家分享一组Blender格式的资源,56个原神角色模型,2K高清贴图,带骨

    2024年02月11日
    浏览(85)
  • vue+element仿原神实现好看的个人中心

    目录 一、仿原神效果图  二、代码实现 1.项目截图 2.路由配置 完整源码 3.个人中心index源码 4.用户信息页面源码 5.我的合集源码 三、总结 2011年,24岁的上海交通大学研究生刘伟、蔡浩宇、罗宇皓三人拿到上海市科技创业中心大学生创业基金会“雏鹰计划”10万元资助创办米

    2024年02月03日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包