【问题标题】:Move each character of a div based on mouse movement根据鼠标移动移动 div 的每个字符
【发布时间】:2014-09-20 09:13:43
【问题描述】:

我正在开发一个网站,但我不知道如何创建如下所示的 javascript 动画:

我有一个div,上面有一些文字,当用户将鼠标移到此文字上时,我希望每个字符彼此独立移动,以保持与它有一定的距离(鼠标)。另外,我希望这个动画有旋转,但现在已经不那么重要了。这是一个图像解释:

这是我目前所做的:

HTML:

<div class="div1">Hello World</div>

Javascript:

var chars = $(".div1").html().split('');
$(".div1").empty();
for(var i = 0; i < chars.length; i++){
    $(".div1").append("<span class='letter'>"+chars[i]+"</span>");
}

JSFiddle


有人可以帮我实现这个效果吗?我不知道如何继续,也没有帮助我的网站或答案。您可以使用 jQuery 或纯 JavaScript,但请保持简单!谢谢。

【问题讨论】:

  • 计算角度和距离,并将它们应用到字符上 * geometry *
  • 但是,如果所有字符都具有相同的类,我如何才能相互独立地应用每个字符的角度和距离?
  • 为每一个应用不同的 CSS 值
  • @TiagoMarinho - 我不认为这是这样做的方法,但这取决于你想要做什么?也许从更接近这个的东西开始 -> jsfiddle.net/adeneo/6fk8H/4
  • @Foreever 我要学习!

标签: javascript jquery html


【解决方案1】:

哦,我们开始吧,我已经找到了解决方案。

我所做的是为每个字符使用不同的类名(.letter + 字符编号),然后创建了一种根据鼠标位置和与每个字符相比的距离来移动字符的方法,例如,当鼠标与字符的距离小于X,且鼠标Y小于字符Y,则字符向下。

感谢adeneoDerek

以下是相关代码:

JavaScript:

var chars = $(".div1").html().split('');
$(".div1").empty();
for (var i = 0; i < chars.length; i++) {
    $(".div1").append("<span class='letter" + i + "'>" + chars[i] + "</span>");
    $(".letter" + i).css({
        "position":"relative",
    });
    $(".letter" + i).css({
        "transition": "0.5s"
    });
}

$(document).on("mousemove", function (e) {
    for (var i = 0; i < chars.length; i++) {
        var x = e.pageX,
            y = e.pageY;
        var distx = x - $(".letter" + i).offset().left + ($(".letter" + i).width() / 2);
        var disty = y - $(".letter" + i).offset().top;

    if (Math.abs(distx) < 24 && Math.abs(disty) < 24) {
        if (distx > 6 || distx < -6) {
            if (x < $(".letter" + i).offset().left) {
                $(".letter" + i).css({
                    "left": + (24 / Math.abs(distx) * Math.abs(distx)),
                        "position": "relative"
                });
            } else {
                $(".letter" + i).css({
                    "left": - (24 / Math.abs(distx) * Math.abs(distx)),
                        "position": "relative"
                });
            }
        }

        if (disty > 12 || disty < -12) {
            if (y < $(".letter" + i).offset().top + 6) {
                $(".letter" + i).css({
                    "top": + (24 / Math.abs(disty) * Math.abs(disty)),
                        "position": "relative"
                });
            } else {
                $(".letter" + i).css({
                    "top":  - (24 / Math.abs(disty) * Math.abs(disty)),
                        "position": "relative"
                });
            }
        }
    }
    distx = 0;
    disty = 0;
}

});

HTML:

<div class="div1">Hello World</div>

Updated JSFiddle with CSS Transitions to improve smoothness

【讨论】:

  • 哦,太好了,你找到了一种方法;),也许你可以把它变成一个 js“类”,​​以便更好地组织以供进一步使用 =)
【解决方案2】:

好吧,既然你说你想学,我就给你一个代码来帮助你,但是你必须自己解决,我没有测试它,我只是盲目地写它,所以它可能不会工作,但可能会让您对必须做什么有一个很好的了解。

HTML:

<div class="container">
    <div id="coolDiv" class="scatterContainer">Hello World</div>
</div>

CSS:

*{margin:0;}
span:hover{
    color:#0CF;
}
.scatterContainer{
    display: inline;
}
.container {
    margin: 30px auto;
}

Javascript

LetterScatterer = (function() {

  function LetterScatterer(id) {

    this.id = id
    this.$el = $('#' + this.id);
    this.rangeOfaction = 3; // Number of characters to affect
    this.maxVerticalMovement = 10; // Value in px
    this.minVerticalMovement = 2
    this.duration = 100; // In miliseconds



    // Event Listeners

    this.$el.on(mousemove((function(_this){

        return function(e){

            var x = e.pageX;
            var y = e.pageY;

            return _this.scatter(x, y);
        }

    })(this));

  }

  LetterScatterer.prototype.splitCharacters = function() {
    var nodes = [];
    var nodesQ = 0;
    var _this = this;
    this.chars = $el.text().split('');
    $el.empty();


    for(var i = 0; i < chars.length; i++){
        var markup = "<span class='letter'>"+chars[i]+"</span>";
        nodes.push(markup);
    }

    this.$nodes = $(nodes);

    this.nodesWidth = [];
    this.$nodes.each(function(){
        var width = $(this).outerWidth();
        _this.nodesWidth.push(width);
    });

    $el.append(this.$nodes);


  }

  LetterScatterer.prototype.scatter = function(x, y) {
    var epicenter;
    var offset = 0;
    var midPoint, farestLeft;

    for(var i = 0, len = this.nodesWidth.length; i < len; i++){
        offset += this.nodesWidth[i];
        if(x <= offset){
            epicenter = i;
            break;
        }
    }

    leftRange = (this.rangeOfaction - 1) / 2; // We remove one, this is our epicenter, then we get left and right halves


    farestLeft = epicenter - leftRange;
    for(var i = farestLeft; i < this.rangeOfaction; i++){
        this.animateY($node[i]);
    }


  }


  LetterScatterer.prototype.animateY = function(node, verticalDisplacement) {
    var $node = $(node);
    $node.animate({margin-top: verticalDisplacement + 'px'}, this.duration);
  }



  return LetterScatterer;

})();

letterScatterer = new LetterScatterer('coolDiv');

您在代码中看到的是一个类类函数,首先您将包含要分散的文本的元素的 id 传递给它。有一些配置变量,动作范围可以说,如果您将鼠标悬停在一个字符上,左右多少个字符(也包括当前悬停的元素)应该被动画化,最大和最小垂直移动,确定如何much 应该移动悬停的那个(最大),距离较远的将使用 min,介于两者之间的应该插值,但我没有编码那么远。

然后我们得到了一个mousemove监听器,它调用方法scatter,这个方法通过添加每个字符宽度来找到当前悬停的项目,但是现在我想,在span中添加一个监听器应该更容易,并使用 jQuery 方法 index() 获取该元素的当前索引,然后根据该索引为该元素和范围内的元素设置动画。如果需要,您必须创建计算旋转和 x 运动的代码,但我想我给了你很多开始,我花了一段时间来编写它,所以我希望它有所帮助,这个答案满足你的问题。 :)

【讨论】:

  • 非常感谢您的帮助,但是由于您的代码需要更多的 HTML 标记、更多的 JavaScript 行并且未经测试,我认为我的解决方案更好(我已经在这里回答了我的解决方案,就像您可以查看您是否向下滚动,但我不能在不到 2 天内接受它是正确的)。无论如何,我非常感谢所有帮助过我的人。
  • 欢迎您,您可以改进此代码以使用相同的标记量,它有更多的javascript,但可能只是有更多的结构。但是你的代码已经可以工作了,所以它很简单:P,祝你的项目好运;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 2015-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
  • 2023-03-31
相关资源
最近更新 更多