admin管理员组

文章数量:1414604

I'm developing a site and I don't know how to create a javascript animation that looks like this:

I have a div that have some text on it, and when the user moves his mouse over this text, I want each character to move independently of each other, in order to maintain a certain distance from it (the mouse). Also, I want this animation to have rotation, but it isn't that important now. Here's an image explanation:

Here's what I did so far:

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


Can someone help me to achieve this effect? I don't know how to proceed and there's no site or answer that helped me. You can use jQuery or pure JavaScript but, please, keep it simple! Thank you.

I'm developing a site and I don't know how to create a javascript animation that looks like this:

I have a div that have some text on it, and when the user moves his mouse over this text, I want each character to move independently of each other, in order to maintain a certain distance from it (the mouse). Also, I want this animation to have rotation, but it isn't that important now. Here's an image explanation:

Here's what I did so far:

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


Can someone help me to achieve this effect? I don't know how to proceed and there's no site or answer that helped me. You can use jQuery or pure JavaScript but, please, keep it simple! Thank you.

Share Improve this question asked May 12, 2014 at 3:17 Tiago MarinhoTiago Marinho 2,2361 gold badge21 silver badges38 bronze badges 17
  • Calculate the angle and distance, and apply them on the characters * geometry * – Derek 朕會功夫 Commented May 12, 2014 at 3:24
  • But how can I apply the angle and distance for each character independently of each other, if all the characters have the same class? – Tiago Marinho Commented May 12, 2014 at 3:25
  • Apply different CSS values for each of them – Derek 朕會功夫 Commented May 12, 2014 at 3:27
  • 2 @TiagoMarinho - I don't think that's the way to do it, but that depends on what you're trying to do? Maybe start with something closer to this -> jsfiddle/adeneo/6fk8H/4 – adeneo Commented May 12, 2014 at 4:00
  • 1 @Foreever I want to learn! – Tiago Marinho Commented May 12, 2014 at 4:08
 |  Show 12 more ments

2 Answers 2

Reset to default 5

Oh here we go, I've found a solution for this.

What I did was using a different class name for each character (.letter + character number) and then created a way of moving the characters depending on the mouse position and distance pared to each character, so, for example, when the distance between the mouse and a character is less than X, and the mouse Y is less than the character Y, then the character will go down.

Thanks to adeneo and Derek

Here's the relevant code:

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

Well since you say yo want to learn, i'll give a code to help you out, but you have to work your way through, i haven't test it, i just wrote it blindly so it propably won't work but might give you a good idea of what must be done.

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');

What you see in the code is a classlike function, first you pass it the id of the element containing the text that will be scattered. There are some config varaibles, range of action is lets say, if you mouse over one character, how many characters to the left and to the right (also including the current hovered element) should be animated, the max and min verticalMovement, determines how much should move the one that is hovered (max) and those further apart will use min, those in between should interpolate, but i didn't code that far.

We then got a mousemove listener, that calls the method scatter, this method finds which items is currently hovered by adding up each character widht, but now i think about it, it should be easier to just add a listener to the span, and get the current index of that element with the jQuery method index(), then based on that index you animate that one and those in the range. You must create the code that calculates the rotation, and x movement if you want to, but i think i gave you a lot to start, it took me a while to code it, so i hope it helps and this answer satisfies your question. :)

本文标签: javascriptMove each character of a div based on mouse movementStack Overflow