Прокрутка текста ссылки при наведении - эффект бесконечного выделения - PullRequest
0 голосов
/ 22 марта 2020

Я ищу эффективное и гладкое решение для ссылок, которые прокручивают свой текст внутри их блока встроенного блока, как эффект выделения.

 $(document).ready(function() {
    
    function scroll(ele){
    	var s = $(ele).text().substr(1)+$(ele).text().substr(0,1);
	    $(ele).text(s);
    }

    scrollInterval = null;
    function startScrolling(e) {
        if (!scrollInterval) {
            scrollInterval = setInterval(function(){
                scroll(e)
            },100);
        }
    }

    function stopScrolling(e) {
        clearInterval(scrollInterval);
        scrollInterval = null;
    }

    $(".mali").hover(function(){
        startScrolling($(this));
    });

    $(".mali").mouseout(function(){
        stopScrolling($(this));
    });

    $(".mali").mousedown(function(){
        stopScrolling($(this));
    });

  });
.mali {
        display: inline-block;
        background: black;
        color: white;
        padding: 10px;  
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.

Мое решение на данный момент - это то, что я действительно нашел здесь на stackoverlow в другом потоке и пытался работать с ним.

Два проблемы.

1.) Поскольку в основном используется интервал до l oop, состоящий из одиночных букв, этот эффект не очень плавный. Эффект заикается.

У кого-нибудь есть идея, как сделать это более плавным? Возможно, в этом случае вообще не используйте этот метод и, возможно, используйте переход CSS для анимации текста?

2.) У кого-нибудь есть умное решение о том, как вернуться в исходное состояние, как только я зависать? Я хочу, чтобы эффект зависал, но при перемещении мыши от ссылки она должна анимироваться обратно в исходное текстовое состояние.

Спасибо, Мэтт

1 Ответ

1 голос
/ 22 марта 2020

2) Вы можете сохранить исходное состояние, а затем просто восстановить его:

$(document).ready(function() {
    
    function scroll(ele){
    	var s = $(ele).text().substr(1)+$(ele).text().substr(0,1);
	    $(ele).text(s);
    }

    scrollInterval = null;
    function startScrolling(e) {
        if (!scrollInterval) {
            $(e).data("text", $(e).text());
            scrollInterval = setInterval(function(){
                scroll(e)
            },100);
        }
    }

    function stopScrolling(e) {
        clearInterval(scrollInterval);
        scrollInterval = null;
        $(e).text($(e).data("text"));
    }

    $(".mali").hover(function(){
        startScrolling($(this));
    });

    $(".mali").mouseout(function(){
        stopScrolling($(this));
    });

    $(".mali").mousedown(function(){
        stopScrolling($(this));
    });

  });
.mali {
        display: inline-block;
        background: black;
        color: white;
        padding: 10px;  
        transition: all .2s;
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.

1) Как плавная анимация, я думал об этом как о Po C. Может быть, это поможет вам с дальнейшими идеями.

$(document).ready(function() {
    // Those global data could be stored in element's data.
    var indent = 0,
        width = 0,
        padding = 10;
    function scroll(ele){
      // Every iteration decrease indent by value
      indent -= 1;
      
      // If is indent greater than or equal than real width
      // (width with padding) reset indent.
      if(-indent >= width+padding)
        indent = 0;
       
       // Aplly property
      $(ele).css("text-indent", indent);
    }

    var scrollInterval = null;
    function startScrolling(e) {
        if (!scrollInterval) {
            // Get text and real width
            let text = $(e).text();
            width = $(e).width()
          
            $(e)
              // Set real width & height, so that container stays
              .width($(e).width())
              .height($(e).height())
              
              // Save text to data for reset
              .data("text", text)
              
              // Add 2 spans with text:
              // <span>text</span><span>text</span>
              // Where second span has defined padding on the left
              .html($("<span>").text(text))
              .append($("<span>").text(text).css("padding-left", padding+"px"));
             
           resumeScrolling(e);
        }
    }

    function stopScrolling(e) {
        pauseScrolling(e);
        
        // Reset
        $(e)
          // Revert real text and reset indent
          .text($(e).data("text"))
          .css("text-indent", indent = 0);
    }

    function pauseScrolling(e) {
        clearInterval(scrollInterval);
        scrollInterval = null;
    }

    function resumeScrolling(e) {
        if (!scrollInterval) {
          // Every 30ms repeat animation. It must be at least 25x per second
          // so it runs smoothly. (So 1 - 40).
          scrollInterval = setInterval(function(){
            scroll(e)
          },30);
       }
    }

    $(".mali").hover(function(){
        startScrolling($(this));
    });

    $(".mali").mouseout(function(){
        stopScrolling($(this));
    });

    $(".mali").mousedown(function(){
        stopScrolling($(this));
    });

    $("#start").click(function(){
      startScrolling($(".mali"));
    });
    $("#stop").click(function(){
      stopScrolling($(".mali"));
    });
    $("#pause").click(function(){
      pauseScrolling($(".mali"));
    });
    $("#resume").click(function(){
      resumeScrolling($(".mali"));
    });

  });
.mali {
  display: inline-block;
  background: black;
  color: white;
  padding: 10px;
  /*
  This could help, but you can't reset text-indent without animation.
  transition: all .1s;
  */
  overflow: hidden;
  vertical-align: middle;
}

/* When you hover element, new span elements
can't take pointer events, so your elements
stays hovered. */
.mali span {
  pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Something <a href="#" class="mali">something&nbsp;darkside</a>, Something something complete.

<br><br>
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="pause">Pause</button>
<button id="resume">Resume</button>

Идея заключается в следующем:

  • make element overflow:hidden;, поэтому текст не будет переполнен
  • установить фиксированное измерение
  • дублировать текст внутри
  • изменять отступ текста каждые x миллисекунд (x <40, чтобы он был плавным, должен быть не менее 25fps) </li>
  • при переполнении, сбросьте его так, чтобы оно могло быть бесконечно l oop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...