在JavaScript中模拟空调效果的前端界面的交互和状态变化(附完整源码)

在JavaScript中模拟空调效果的前端界面的交互和状态变化(附完整源码)

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>实现空调自由</title>
  <style>
    .cuboid{--height:6;--width:6;--depth:6;--hue:240;--sat:10%;--lum:40%;height:calc(var(--height) * 1vmin);width:calc(var(--width) * 1vmin);position:absolute}.cuboid .side{position:absolute;top:50%;left:50%;height:100%;width:100%;border-radius:2px;background:hsl(var(--hue),var(--sat),var(--lum))}.cuboid .side:nth-of-type(1){transform:translate3d(-50%,-50%,calc(var(--depth) * 0.5vmin));--lum:60%}.cuboid .side:nth-of-type(2){transform:translate3d(-50%,-50%,calc(var(--depth) * -0.5vmin)) rotateY(180deg)}.cuboid .side:nth-of-type(3){width:calc(var(--depth) * 1vmin);transform:translate(-50%,-50%) rotateY(90deg) translate3d(0,0,calc(var(--width) * 0.5vmin));--lum:70%}.cuboid .side:nth-of-type(4){width:calc(var(--depth) * 1vmin);transform:translate(-50%,-50%) rotateY(-90deg) translate3d(0,0,calc(var(--width) * 0.5vmin));--lum:70%}.cuboid .side:nth-of-type(5){height:calc(var(--depth) * 1vmin);transform:translate(-50%,-50%) rotateX(90deg) translate3d(0,0,calc(var(--height) * 0.5vmin));--lum:20%}.cuboid .side:nth-of-type(6){height:calc(var(--depth) * 1vmin);transform:translate(-50%,-50%) rotateX(-90deg) translate3d(0,0,calc(var(--height) * 0.5vmin));--lum:50%}.cuboid .side:nth-of-type(7){height:calc(var(--depth) * 0.225vmin);transform:translate(-50%,-50%) rotateX(-90deg) translate3d(0,2.25vmin,calc(var(--height) * 0.5vmin));--lum:30%}*{transform-style:preserve-3d;box-sizing:border-box}body{display:flex;align-items:center;justify-content:center;padding:0;margin:0;width:100vw;height:100vh;overflow:hidden;perspective:100vmin;perspective-origin:bottom;background:radial-gradient(circle at 50% 100%,#fff,#fff,#666)}.content{width:80vmin;height:50vmin;transform:rotateY(0deg) rotateX(0deg)}.box{--width:60;--height:15}.ac{left:10vmin;position:absolute;z-index:1}.cuboid.box>.side:nth-of-type(1){clip-path:polygon(0% 0%,100% 0%,100% 75%,0% 75%,0% 100%)}.cuboid.box>.side:nth-of-type(3){clip-path:polygon(0% 0%,100% 0%,100% 100%,75% 100%,0% 75%)}.cuboid.box>.side:nth-of-type(4){clip-path:polygon(0% 0%,100% 0%,100% 75%,25% 100%,0% 100%)}.box>.side:nth-of-type(6){transform:translate(-50%,-50%) rotateX(-50deg) translate3d(0vmin,3.2vmin,4.75vmin);background:linear-gradient(180deg,hsl(var(--hue),var(--sat),var(--lum)) 1.1vmin,#fff0 0 calc(100% - 3.15vmin),hsl(var(--hue),var(--sat),var(--lum)) 0 calc(100% - 2.55vmin),#fff0 0 calc(100% - 1vmin),hsl(var(--hue),var(--sat),var(--lum)) 0 100%),linear-gradient(90deg,hsl(var(--hue),var(--sat),var(--lum)) 3vmin,#fff0 3vmin calc(100% - 3vmin),hsl(var(--hue),var(--sat),var(--lum)) 0 100%)}.box>.side:nth-of-type(6):before,.box>.side:nth-of-type(6):after{content:"";--lum:60%;position:absolute;background:hsl(var(--hue),var(--sat),var(--lum));width:53.5vmin;height:1.5vmin;top:1.225vmin;left:3.25vmin;transform-origin:50% 75%;transform:rotateX(0deg);animation:fanfan-move 8s ease-in-out 0s infinite;animation-play-state:paused}@keyframes fanfan-open{100%{transform:rotateX(-120deg)}}@keyframes fanfan-close{0%{transform:rotateX(-120deg)}100%{transform:rotateX(0deg)}}@keyframes fanfan-move{0%,100%{transform:rotateX(-120deg)}50%{transform:rotateX(-40deg)}}#btn-off:checked~.content .ac .box>.side:nth-child(6):before,#btn-off:checked~.content .ac .box>.side:nth-child(6):after{animation:fanfan-close 4s ease-in-out 0s 1;animation-fill-mode:forwards}#btn-hot:checked~.content .ac .box>.side:nth-child(6):before,#btn-hot:checked~.content .ac .box>.side:nth-child(6):after,#btn-cold:checked~.content .ac .box>.side:nth-child(6):before,#btn-cold:checked~.content .ac .box>.side:nth-child(6):after{animation:fanfan-open 4s ease-in-out 0s 1;animation-fill-mode:forwards}#btn-hot:checked~#btn-fan:checked~.content .ac .box .side:nth-child(6):before,#btn-hot:checked~#btn-fan:checked~.content .ac .box .side:nth-child(6):after,#btn-cold:checked~#btn-fan:checked~.content .ac .box .side:nth-child(6):before,#btn-cold:checked~#btn-fan:checked~.content .ac .box .side:nth-child(6):after{animation:fanfan-move 8s ease-in-out 0s infinite}.box>.side:nth-of-type(6):after{top:3.5vmin}label{transform:translateZ(3vmin);position:absolute;right:1vmin;top:0.85vmin;height:2.825vmin;min-width:2.825vmin;cursor:pointer;font-size:1.75vmin;transition:0.4s ease 0s}label[for="btn-cold"]{top:4.2vmin}label[for="btn-fan"]{top:7.5vmin}label[for="btn-off"]{background:repeating-linear-gradient(90deg,#4caf50 0 3px,#fff0 0 7px);background:#fff0;top:9.5vmin;transform:translateZ(3.5vmin)}#btn-hot:checked~.content .ac .box label[for="btn-off"]{top:0.85vmin}#btn-cold:checked~.content .ac .box label[for="btn-off"]{top:4.2vmin}#btn-off:checked~.content .ac .box label[for="btn-off"]{opacity:0;pointer-events:none}label.cuboid{--width:2.8;--height:2.8;--depth:1.5}label.cuboid .side:first-child{display:flex;align-items:center;justify-content:center;line-height:0;background:#9794a9}#btn-hot:checked~.content .ac .box label[for="btn-hot"],#btn-cold:checked~.content .ac .box label[for="btn-cold"],#btn-fan:checked~.content .ac .box label[for="btn-fan"]{transform:translateZ(2.5vmin)}#btn-hot:checked~.content .ac .box label[for="btn-hot"] .side:nth-child(1){background:#f59;box-shadow:0 0 6px 1px #f00}#btn-cold:checked~.content .ac .box label[for="btn-cold"] .side:nth-child(1){background:#aeffff;box-shadow:0 0 6px 1px cyan}#btn-fan:checked~.content .ac .box label[for="btn-fan"] .side:nth-child(1){background:#fff;box-shadow:0 0 6px 1px #fff}input{display:none}.air{position:absolute;width:66%;height:150%;left:17%;transform-origin:50% 0;transform:rotateX(25deg) translateZ(0.5vmin);top:27%;z-index:-1}.air:before,.air:after{--air:#00f3;position:absolute;width:100%;height:0%;min-height:0;background:repeating-linear-gradient(90deg,#fff0 0 3vmin,var(--air) 4.15vmin);content:"";filter:blur(10px);transition:all 1.5s ease 2s;transform:translateZ(1vmin);background-size:200% 100%;background-repeat:repeat;background-position:0% 0;animation:air-fan2 40s linear 0s infinite alternate}.air:after{transform:translateZ(-1vmin) rotate(180deg)}#btn-hot:checked~#btn-fan:checked~.content .air,#btn-cold:checked~#btn-fan:checked~.content .air{animation:air-fan 4s ease-in-out 0s infinite alternate}@keyframes air-fan{100%{transform:rotateX(80deg);background-position:100% 0}}@keyframes air-fan2{100%{background-position:100% 0}}#btn-hot:checked~.content .air:before,#btn-hot:checked~.content .air:after{min-height:80vmin;--air:rgb(255,55,0)}#btn-cold:checked~.content .air:before,#btn-cold:checked~.content .air:after{min-height:80vmin;--air:rgba(16,205,226,0.788)}
  </style>
</head>

<body>

  <input type="radio" name="btns" id="btn-hot">
  <input type="radio" name="btns" id="btn-cold">
  <input type="radio" name="btns" id="btn-off" checked>
  <input type="checkbox" name="fan" id="btn-fan">

  <div class="content">
    <div class="ac">
      <div class="cuboid box">
        <div class="side"></div>
        <div class="side"></div>
        <div class="side"></div>
        <div class="side"></div>
        <div class="side"></div>
        <div class="side"></div>
        <div class="side"></div>
        <label for="btn-hot" class="cuboid">
          <div class="side">&#128293;</div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
        </label>
        <label for="btn-cold" class="cuboid">
          <div class="side">&#10052;</div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
        </label>
        <label for="btn-fan" class="cuboid">
          <div class="side">&#127744;</div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
          <div class="side"></div>
        </label>
        <label for="btn-off"></label>
      </div>
    </div>
    <div class="air"></div>
  </div>
  <script>
    var rotateDiv=document.getElementById('rot');var rotateIcons=document.getElementById('rot-icons');var clickRotateDiv=document.getElementById('click-rot');var angle=0;clickRotateDiv.onclick=function(){angle+=60;rotateDiv.style.transform='rotate('+angle+'deg)';rotateIcons.style.transform='rotate('+angle+'deg)'};var step=2;var color1='rgba(0,0,0,0.5)';var color2='rgba(0,0,0,0.1)';var gradient=' conic-gradient(';for(var i=0;i<360;i+=step){var color=i%(2*step)===0?color1:color2;gradient+=color+' '+i+'deg, '}gradient=gradient.slice(0,-2)+'), rgb(85 93 108)';rotateDiv.style.background=gradient;var toggles=document.querySelectorAll('.toggle');var tempElement=document.querySelector('.temp');let isAnimating=false;toggles.forEach(function(toggle){toggle.addEventListener('click',function(){if(this.classList.contains('active')||isAnimating){return}toggles.forEach(function(toggle){toggle.classList.remove('active')});this.classList.add('active');var tempValue=parseFloat(tempElement.textContent);if(this.id==='toggle-cel'){var celsius=Math.round((tempValue-32)*5/9);tempElement.textContent=celsius+'°C'}else if(this.id==='toggle-far'){var fahrenheit=Math.round(tempValue*9/5+32);tempElement.textContent=fahrenheit+'°F'}})});let currentTempF=34;function easeInOutCubic(t){return t<.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1}function changeTemp(element,newTemp){let unit=element.innerHTML.includes("F")?"°F":"°C";let currentTemp=unit==="°F"?currentTempF:Math.round((currentTempF-32)*5/9);let finalTemp=unit==="°F"?newTemp:Math.round((newTemp-32)*5/9);let duration=2000;let startTime=null;function animate(currentTime){if(startTime===null){startTime=currentTime}let elapsed=currentTime-startTime;let progress=Math.min(elapsed/duration,1);progress=easeInOutCubic(progress);let tempNow=Math.round(currentTemp+(progress*(finalTemp-currentTemp)));element.innerHTML=`${tempNow}${unit}`;if(progress<1){requestAnimationFrame(animate)}else{currentTempF=newTemp;isAnimating=false}}isAnimating=true;requestAnimationFrame(animate)}window.onload=function(){const sixths=Array.from(document.querySelectorAll('.sixths'));let index=0;let temp=document.querySelector('.temp');document.querySelector('#rot-icons').addEventListener('click',()=>{sixths[index].classList.remove('active');index=(index+1)%sixths.length;sixths[index].classList.add('active');if(index==0){changeTemp(temp,34);console.log("sun")document.querySelector('#mountains').classList.remove("snow");document.querySelector('#mountains').classList.remove("clouds")}else if(index==1){changeTemp(temp,27);console.log("sunset")document.querySelector('#mountains').classList.add("sunset")}else if(index==2){changeTemp(temp,14);console.log("moon")document.querySelector('#mountains').classList.remove("sunset");document.querySelector('#mountains').classList.add("moon")}else if(index==3){changeTemp(temp,16);console.log("clouds")document.querySelector('#mountains').classList.add("clouds")}else if(index==4){changeTemp(temp,8);console.log("storm")document.querySelector('#mountains').classList.add("storm")}else if(index==5){changeTemp(temp,-4);console.log("snow")document.querySelector('#mountains').classList.remove("moon");document.querySelector('#mountains').classList.remove("storm");document.querySelector('#mountains').classList.add("snow")}let loadingBar=document.querySelector('.loading-bar');loadingBar.classList.add('active');setTimeout(()=>{loadingBar.classList.remove('active')},1200)})};
  </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值