2015-05-21 12 views
12

robię tej wtyczki, które odbywają słowa i czyni je pulsować na ekranie:aby słowa pulsować i zmiana miejsca losowo

Najpierw pojawiają się i rosną, a potem zniknąć, zmienić miejsce i ponownie pojawić

wtyczka

robocza:

+ function($) { 
 

 
    var Pulsate = function(element) { 
 
    var self = this; 
 
    
 
    self.element = element; 
 
    self.max = 70; 
 
    self.min = 0; 
 
    self.speed = 500; 
 
    self.first = true; 
 
    self.currentPlace; 
 
    self.possiblePlaces = [ 
 
     { 
 
     id: 0, 
 
     top: 150, 
 
     left: 150, 
 
     }, 
 
     { 
 
     id: 1, 
 
     top: 250, 
 
     left: 250, 
 
     }, 
 
     { 
 
     id: 2, 
 
     top: 350, 
 
     left: 350, 
 
     }, 
 
     { 
 
     id: 3, 
 
     top: 250, 
 
     left: 750, 
 
     }, 
 
     { 
 
     id: 4, 
 
     top: 450, 
 
     left: 950, 
 
     } 
 
    ]; 
 
    
 
    }; 
 
    
 
    Pulsate.prototype.defineRandomPlace = function() { 
 
    var self = this; 
 
    self.currentPlace = self.possiblePlaces[Math.floor(Math.random() * self.possiblePlaces.length)]; 
 
    
 
    if(!self.possiblePlaces) self.defineRandomPlace; 
 
    
 
    
 
    
 
    self.element.css('top', self.currentPlace.top + 'px'); 
 
    self.element.css('left', self.currentPlace.left + 'px'); 
 
    }; 
 
    
 
    Pulsate.prototype.animateToZero = function() { 
 
    var self = this; 
 
    
 
    self.element.animate({ 
 
     'fontSize': 0, 
 
     'queue': true 
 
    }, self.speed, function() { 
 
     self.defineRandomPlace(); 
 
    }); 
 
    
 
    }; 
 
    
 
    Pulsate.prototype.animateToRandomNumber = function() { 
 
    var self = this; 
 
    
 
    self.element.animate({ 
 
     'fontSize': Math.floor(Math.random() * (70 - 50 + 1) + 50), 
 
     'queue': true 
 
    }, self.speed, function() { 
 
     self.first = false; 
 
     self.start(); 
 
    }); 
 
    }; 
 
    
 
    Pulsate.prototype.start = function() { 
 
    var self = this; 
 
    
 
    if (self.first) self.defineRandomPlace(); 
 
    if (!self.first) self.animateToZero(); 
 
    
 
    self.animateToRandomNumber(); 
 
    }; 
 

 

 
    $(window).on('load', function() { 
 
    $('[data-pulsate]').each(function() { 
 
     var element = $(this).data('pulsate') || false; 
 
     
 
     if (element) { 
 
     element = new Pulsate($(this)); 
 
     element.start(); 
 
     } 
 

 
    }); 
 

 
    }); 
 

 
}(jQuery);
body { 
 
    background: black; 
 
    color: white; 
 
} 
 

 
.word { 
 
    position: absolute; 
 
    text-shadow: 0 0 5px rgba(255, 255, 255, 0.9); 
 
    font-size: 0px; 
 
} 
 

 

 
.two { 
 
    position: absolute; 
 
    color: white; 
 
    left: 50px; 
 
    top: 50px; 
 
} 
 
div { 
 
    margin-left: 0px; 
 
}
<span class="word" data-pulsate="true">Love</span> 
 
<span class="word" data-pulsate="true">Enjoy</span> 
 
<span class="word" data-pulsate="true">Huggs</span> 
 

 

 

 

 

 
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

Jeśli zauważysz, że określenie miejsca, że ​​słowo może g wiersz w self.possiblePlaces, a jeśli zauważysz animację, czasami więcej niż jedno słowo może wzrosnąć w jednym miejscu, moim celem jest tutaj poprosić o pomoc. Jak mogę zrobić dwa słowa, które nigdy nie rosną w tym samym miejscu?

starałem się zrobić tak:

W defineRandomPlace wybiorę losowy przedmiot wewnątrz mojej tablicy possiblePlaces:

Pulsate.prototype.defineRandomPlace = function() { 
    var self = this; 
    self.currentPlace = self.possiblePlaces[Math.floor(Math.random() * self.possiblePlaces.length)]; 

    if(!self.possiblePlaces) self.defineRandomPlace; 


    delete self.possiblePlaces[self.currentPlace.id]; 
    self.element.css('top', self.currentPlace.top + 'px'); 
    self.element.css('left', self.currentPlace.left + 'px'); 
    }; 

Zawiadomienie delete, najpierw sklonować wybrany obiekt, po usunę ale zachowaj swoje miejsce w szyku.

Po animacja skończyła, I umieścić obiekt w tablicy ponownie, przed rozpoczęciem na nowo:

Pulsate.prototype.animateToZero = function() { 
    var self = this; 

    self.element.animate({ 
     'fontSize': 0, 
     'queue': true 
    }, self.speed, function() { 
     self.possiblePlaces[self.currentPlace.id] = self.currentPlace; 
     self.defineRandomPlace(); 
    }); 

Ale to nie miało znaczenia.

Dzięki!

Pen: http://codepen.io/anon/pen/waooQB

+0

http://codepen.io/anon/pen/bdBBPE –

+1

że działa! Możesz wytłumaczyć? –

+0

Wyjaśnię poniżej w odpowiedzi;) –

Odpowiedz

4

Moja decyzja to podzielenie strony na wyimaginowane wiersze i zakazanie więcej niż jednego słowa w tym samym wierszu. Sprawdź to proszę.

Uwaga: ponieważ obecnie kod nie obsługuje ponownego obliczania liczby wierszy podczas zmiany rozmiaru dokumentu, pełny widok strony nie będzie wyświetlany poprawnie. Kliknij "odśwież ramkę" lub spróbuj JSFiddle lub coś podobnego.

var pulsar = { 
 
    // Delay between words appearance 
 
    delay: 400, 
 
    // Word animation do not really depend on pulsar.delay, 
 
    // but if you set pulsar.delay small and wordAnimationDuration long 
 
    // some words will skip their turns. Try 1, 2, 3... 
 
    wordAnimationDuration: 400 * 3, 
 
    // Depending on maximum font size of words we calculate the number of rows 
 
    // to which the window can be divided 
 
    maxFontSize: 40, 
 
    start: function() { 
 
    this.computeRows(); 
 
    this.fillWords(); 
 
    this.animate(); 
 
    }, 
 
    // Calculate the height or row and store each row's properties in pulsar.rows 
 
    computeRows: function() { 
 
    var height = document.body.parentNode.clientHeight; 
 
    var rowsCount = Math.floor(height/this.maxFontSize); 
 
    this.rows = []; 
 
    for (var i = 0; i < rowsCount; i++) { 
 
     this.rows.push({ 
 
     index: i, 
 
     isBusy: false 
 
     }); 
 
    } 
 
    }, 
 
    // Store Word instances in pulsar.words 
 
    fillWords: function() { 
 
    this.words = []; 
 
    var words = document.querySelectorAll('[data-pulsate="true"]'); 
 
    for (var i = 0; i < words.length; i++) { 
 
     this.words.push(new Word(words[i], this.wordAnimationDuration, this.maxFontSize)); 
 
    } 
 
    }, 
 
    // When it comes time to animate another word we need to know which row to move it in 
 
    // this random row should be empty at the moment 
 
    getAnyEmptyRowIndex: function() { 
 
    var emptyRows = this.rows.filter(function(row) { 
 
     return !row.isBusy; 
 
    }); 
 
    if (emptyRows.length == 0) { 
 
     return -1; 
 
    } 
 
    var index = emptyRows[Math.floor(Math.random() * emptyRows.length)].index; 
 
    this.rows[index].isBusy = true; 
 
    return index; 
 
    }, 
 
    // Here we manipulate words in order of pulsar.words array 
 
    animate: function() { 
 
    var self = this; 
 
    this.interval = setInterval(function() { 
 
     var ri = self.getAnyEmptyRowIndex(); 
 
     if (ri >= 0) { 
 
     self.words.push(self.words.shift()); 
 
     self.words[0].animate(ri, function() { 
 
      self.rows[ri].isBusy = false; 
 
     }); 
 
     } 
 
    }, this.delay); 
 
    } 
 
} 
 

 
function Word (span, duration, maxFontSize) { 
 
    this.span = span; 
 
    this.inAction = false; 
 
    this.duration = duration; 
 
    this.maxFontSize = maxFontSize; 
 
} 
 

 
/** 
 
    * @row {Numer} is a number of imaginary row to place the word into 
 
    * @callback {Function} to call on animation end 
 
    */ 
 
Word.prototype.animate = function (row, callback) { 
 
    var self = this; 
 
    // Skip turn if the word is still busy in previous animation 
 
    if (self.inAction) { 
 
    return; 
 
    } 
 
    var start = null, 
 
     dur = self.duration, 
 
     mfs = self.maxFontSize, 
 
     top = row * mfs, 
 
     // Random left offset (in %) 
 
     left = Math.floor(Math.random() * 90), 
 
     // Vary then font size within half-max size and max size 
 
     fs = mfs - Math.floor(Math.random() * mfs/2); 
 

 
    self.inAction = true; 
 
    self.span.style.top = top + 'px'; 
 
    self.span.style.left = left + '%'; 
 

 
    function step (timestamp) { 
 
    if (!start) start = timestamp; 
 
    var progress = timestamp - start; 
 
    // Calculate the factor that will change from 0 to 1, then from 1 to 0 during the animation process 
 
    var factor = 1 - Math.sqrt(Math.pow(2 * Math.min(progress, dur)/dur - 1, 2)); 
 
    self.span.style.fontSize = fs * factor + 'px'; 
 
    if (progress < dur) { 
 
     window.requestAnimationFrame(step); 
 
    } 
 
    else { 
 
     self.inAction = false; 
 
     callback(); 
 
    } 
 
    } 
 
    window.requestAnimationFrame(step); 
 
} 
 

 
pulsar.start();
body { 
 
    background: black; 
 
    color: white; 
 
} 
 

 
.word { 
 
    position: absolute; 
 
    text-shadow: 0 0 5px rgba(255, 255, 255, 0.9); 
 
    font-size: 0px; 
 
    /* To make height of the .word to equal it's font size */ 
 
    line-height: 1; 
 
}
<span class="word" data-pulsate="true">Love</span> 
 
<span class="word" data-pulsate="true">Enjoy</span> 
 
<span class="word" data-pulsate="true">Huggs</span> 
 
<span class="word" data-pulsate="true">Peace</span>

8

W przykładzie, zostanie losowo wybierając z listy, która ma pięciu członków, a masz trzy oddzielne słowa, które mogą być wyświetlane, stawiając możliwość nakładania dość wysokie.

Proste podejście do rozwiązania polega na wybraniu pierwszego elementu na liście, usunięciu go z listy i dołączeniu do końca listy za każdym razem. Ponieważ masz więcej pozycji na listach niż pozycje wybierane z niego, masz gwarancję, że nigdy się nie zderzysz.

  1. Udostępnij tę samą listę possiblePlaces między wszystkimi instancjami.
  2. Przesunięcie pierwszego elementu z kolejki i wciśnięcie go na koniec za każdym razem, zamiast wybierania losowo w defineRandomPlace.

Snippet podkreślająC# 2:

// shift a position off the front 
self.currentPlace = possiblePlaces.shift(); 

self.element.css('top', self.currentPlace.top + 'px'); 
self.element.css('left', self.currentPlace.left + 'px'); 

// push it back on the end 
possiblePlaces.push(self.currentPlace); 

Jeśli chcesz to naprawdę losowe, musisz losowo wybrać i usunąć element z tablicy, a nie umieścić go z powrotem do tablicy aż po został użyty. Musisz też zawsze upewnić się, że masz więcej possiblePlaces niż elementów domowych do umieszczenia na stronie.

tak:

Pulsate.prototype.defineRandomPlace = function() { 
    var self = this; 
    var newPlace = possiblePlaces.splice(Math.floor(Math.random()*possiblePlaces.length), 1)[0]; 

    if (self.currentPlace) { 
    possiblePlaces.push(self.currentPlace); 
    } 

    self.currentPlace = newPlace; 

    self.element.css('top', self.currentPlace.top + 'px'); 
    self.element.css('left', self.currentPlace.left + 'px'); 
}; 

Zobacz http://codepen.io/anon/pen/bdBBPE

+0

To bardzo dobrze Ben, ale muszę zapytać. Cant może być całkowita losowo? To bardzo dobrze, naprawdę. Ale ktoś może zauważyć, że istnieje wzór –

+0

Po prostu dla jasności, jeśli mam na przykład 10 spacji i 4 słowa, widzę dowolne wzory, ale jeśli mam 10 miejsc i 9 słów, wzór jest bardzo widoczny. –

+0

Tak, możesz sprawić, że będzie naprawdę losowy. Zaktualizowano. Lista spotów jest jednak ciągle zakodowana, więc następnym krokiem będzie ustalenie losowych miejsc i upewnienie się, że się nie kolidują. Na kolejny dzień. –

2

zaktualizowałem swój konstruktor wtyczki. Zwróć uwagę na zmienną Pulsate.possiblePlaces, zmieniłem deklarację zmiennych w ten sposób, aby móc udostępniać zmienne dane dla wszystkich wystąpień obiektu twojej wtyczki.

var Pulsate = function(element) { 
    var self = this; 

    self.element = element; 
    self.max = 70; 
    self.min = 0; 
    self.speed = 500; 
    self.first = true; 
    self.currentPlace; 
    Pulsate.possiblePlaces = [ 
     { 
      id: 0, 
      top: 150, 
      left: 150, 
     }, 
     { 
      id: 1, 
      top: 250, 
      left: 250, 
     }, 
     { 
      id: 2, 
      top: 350, 
      left: 350, 
     }, 
     { 
      id: 3, 
      top: 250, 
      left: 750, 
     }, 
     { 
      id: 4, 
      top: 450, 
      left: 950, 
     } 
    ]; 

}; 

Dodałem atrybut occupied możliwą do zidentyfikowania tych miejsc, które są już zajęte. Jeśli losowa currentPlace jest już zajęta, szukaj losowego miejsca ponownie.

Pulsate.prototype.defineRandomPlace = function() { 
    var self = this; 
    self.currentPlace = Pulsate.possiblePlaces[Math.floor(Math.random() * Pulsate.possiblePlaces.length)]; 

    if(!Pulsate.possiblePlaces) self.defineRandomPlace; 


    if (!self.currentPlace.occupied) { 
     self.currentPlace.occupied = true; 
     self.element.css('top', self.currentPlace.top + 'px'); 
     self.element.css('left', self.currentPlace.left + 'px'); 
    } else { 
     self.defineRandomPlace(); 
    } 
}; 

każdym razem, gdy element jest ukryty, należy ustawić atrybut occupied do false.

2

małą podpowiedź F = 0.5px X = 100px T = 0,5s

x/f = 200 
200/2 * t * 0.5 = f(shrink->expand until 100px square) per 0.5 seconds 
+0

Jeśli jest to tylko podpowiedź, a nie odpowiedź, powinna zostać opublikowana jako komentarz. – Kmeixner

Powiązane problemy