javascript - 如何在拖动太阳时转换背景?

标签 javascript jquery html css

我创建了一个页面,您可以在其中以弧形拖动太阳图像。当您拖动太阳时,它会从明亮的太阳转变为较暗的太阳,然后转变为月亮。现在我也希望背景图像能够转换。

如何使当前的天空背景图像在太阳弧线的中间逐渐淡入夜空的平铺图像(如下图所示)?

enter image description here

这是“程序”:http://whatisupson.tumblr.com/

var width = 300,
  sun = $("#sun"),
  dark = $("#dark_sun"),
  moon = $("#moon"),
  total = $(window).width()
firstOfThree = (total / 3) * 0,
  secondOfThree = (total / 3) * 1,
  thirdOfThree = (total / 3) * 2;

sun.draggable({
  axis: "x",
  containment: 'body',
  drag: function() {
    var x = sun.offset().left + (sun.width() / 2),
      heightPct = Math.pow((total / 2) - x, 2) / Math.pow($(window).width() / 2, 2);
    this.style["margin-top"] = "" + Math.round(heightPct * 30) + "%";

    dark.css({
      left: x - (sun.width() / 2),
      marginTop: heightPct * 30 + "%"
    });

    $(this).css({
      opacity: (1 - (x / thirdOfThree)) >= 0 ? (1 - (x / thirdOfThree)) : 0,
      marginTop: heightPct * 30 + "%"
    });
    moon.css({
      left: sun.offset().left,
      marginTop: heightPct * 30 + "%"
    });

    if (x > thirdOfThree) {
      dark_opacity = 1 - ((x - thirdOfThree) / (total - x - sun.width() / 2));
      dark.css({
        opacity: dark_opacity
      });
      moon.css({
        opacity: 1
      });
    } else {
      moon.css({
        opacity: 0
      });
      dark.css({
        opacity: 1
      });
    }
  }
});
body {
  background: url(http://i.imgur.com/aZty7Mq.png);
  animation: mymove 4s linear infinite;
  -webkit-animation: mymove 4s linear infinite;
  -moz-animation: mymove 4s linear infinite;
}
@keyframes mymove {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: 40% 0;
  }
}
#moon {
  position: absolute;
  width: 300px;
  height: 300px;
  top: 20%;
  left: 10%;
}
#dark_sun {
  position: absolute;
  width: 300px;
  height: 300px;
  top: 20%;
  left: 10%;
}
#sun {
  position: absolute;
  width: 300px;
  height: 300px;
  top: 20%;
  left: 10%;
}
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

<img id="moon" src="http://i.imgur.com/VmFEwrH.png">
<img id="dark_sun" src="http://i.imgur.com/f3UFHb7.png">
<img id="sun" src="http://i.imgur.com/DGkZYZQ.png">

最佳答案

使用固定图层并过渡固定图层的不透明度。

getOpacity 函数接受两个参数,Z(百分比)和 div 的索引,并使用这些参数(以及元素数量)来计算不透明度,同时确保每个 .bg 在拖动过程中的某个时刻都是完全可见的。它设置并返回 cos 函数中的值。

opacity = A*Math.cos(P*0 + Z*Math.PI - (index*Math.PI)/L) + V

我做了一个可视化created a visualization @desmos.com并添加了一个片段,以便每个人都可以轻松理解它是如何工作的。

$(function(){

    var bg = $(".bg"),
        drag = $(".drag"),
        sun = $("#sun"),
        csel = '#container'; // container selector

    _init();

    // hoistorzs

    function _init(){
        onDrag();
        sun.css({
            opacity:1
          })
          .draggable({
            axis: "x",
            containment: csel,
            drag:onDrag
        });
    }
  
    function getOpacity(Z,index){
        Z = 1 - Math.min(Math.max(0,Z),1); // guarantee 0 < x < 1
        var len = bg.length;
        var A = 1,
            P = 1,
            V = -A + 1,
            x = 0, // we need y at x=zero
            L = len - 1, // resolves fencepost error calculating arc indices
            opacity = A*Math.cos(P*0 + Z*Math.PI - (index*Math.PI)/L) + V; // 0-1;
        return opacity;
    }

    function onDrag(){
        var len = bg.length,
            total = $(csel).width(),
            min=sun.width()/2+8,
            max=total-min,
            x = sun.offset().left + (min),
            p = (x-min)/(max-min),
            w = sun.width(),
            heightPct = Math.pow((total >> 1) - x, 2) / Math.pow(total >> 1, 2),
            rounded = Math.round(heightPct * 30) + "%";

        bg.each(function(i){
            var op = getOpacity(p,i);
            $(this).css({
                opacity:op
            });
        });
      
        drag.each(function(i){
            var op = getOpacity(p,i);
            $(this).css({
                opacity:op > .5 ? 1 : 0,
                left: sun.css("left"),
                top: sun.css("top"),
                marginTop: rounded
            });
          
        })
    }
})
#container{
  width:100%;
  height:100%;  
}
img.drag {
  position: absolute;
  opacity:-1;
  height:30%;
  bottom:10%;
  transition:opacity 1s;
}
div.bg {
  width:100%;
  height:100%;
  position:fixed;
  top:0;
  left:0;
  background-repeat: repeat;
  background-size:cover;
  animation: mymove 40s linear infinite;
}
@keyframes mymove {
  from { background-position: 0 0; }
  to { background-position: 300px 0; }
}
<div id="container">
  <!-- ADD AS MANY IMAGE AS YOU LIKE HERE IN REVERSE ORDER -->
  
  <!-- NIGHT -->
  <div class="bg" id="night" style="background-image:url(http://i.imgur.com/JK3hIxi.gif);"></div>
  <img class="drag" id="moon" src="http://i.imgur.com/VmFEwrH.png">

  <!-- EVENING -->
  <div class="bg" id="evening" style="background-image:url(http://i.imgur.com/9UqDlgv.png)"></div>
  <img class="drag" id="dark_sun" src="http://i.imgur.com/f3UFHb7.png">
  
  <!-- DAY -->
  <div class="bg" id="day" style="background-image:url(http://i.imgur.com/aZty7Mq.png)"></div>
  <img class="drag" id="sun" src="http://i.imgur.com/DGkZYZQ.png">  

</div>

<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>

关于javascript - 如何在拖动太阳时转换背景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33357361/

相关文章:

javascript - 如何使用 jQuery 或 javascript 在 div 内的 insidehtml 文本后添加跨度?

javascript - 如何在 <img src =""> 标签中使用 html 文件作为图像文件的源

javascript - React + Meteor : this. Prop 返回未定义

javascript - 如何在 Elastic beanstalk 中向 Node JS 传递 --harmony 标志

jquery - 使用 Turbolinks 时如何绑定(bind)事件?

javascript - 遍历表格并显示为 Google Chart

html - 当容器元素被内联元素填充时,浏览器如何决定是开始新行还是扩展容器?

html - 使 div 的行为像一个表,而不使用显示 : table

javascript - JS : join()-ing an array of objects

javascript - JS检查两个文本字段是否不为空