Move each character of a div based on mouse movement

前端 未结 2 1637
一生所求
一生所求 2021-02-01 10:17

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 use

2条回答
  •  北海茫月
    2021-02-01 10:56

    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:

    Hello World

    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 = ""+chars[i]+"";
            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. :)

提交回复
热议问题