我正在使用这个插件来获取单词并使它们在屏幕上形成脉动:
首先它们出现并成长,然后它们消失,改变位置并再次出现
工作插件:
+ 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>
如果您注意到我在self.possiblePlaces中定义了单词可以增长的位置,并且如果您注意到动画,有时候一个单词可以在一个地方生长,我的目标就是寻求帮助。我怎么能说两个字永远不会在同一个地方长大?
我试图这样做:
在defineRandomPlace中,我在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');
};
注意删除,首先我克隆所选对象,在我删除它之后但保留在数组中的位置。
动画结束后,我再次将对象放入数组中,然后重新开始:
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();
});
但它没有任何区别。
谢谢!
答案 0 :(得分:8)
在您的示例中,您是从具有五个成员的列表中随机选择的,并且您可以显示三个单独的单词,从而使重叠的可能性相当高。
一种简单的解决方法是选择列表中的第一项,将其从列表中删除,然后每次追加到列表的末尾。由于您在列表中的位置多于从中选择的项目,因此您可以保证不会发生冲突。
3214
。possiblePlaces
中随机选择。突出显示片段#2:
defineRandomPlace
如果你想让它真正随机,你需要从数组中随机选择和删除一个项目,并且在它被使用之前不要将它放回到数组中。您还需要始终确保您拥有的// 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);
比您在页面上放置的dom元素多。{1}}。
像这样:
possiblePlaces
答案 1 :(得分:4)
我的决定是将页面划分为虚数行并禁止同一行中的多个单词。请检查一下。
注意:由于代码当前不支持重新计算文档大小调整的行数,因此无法正确显示整页视图。点击“重新加载框架”或尝试JSFiddle或smth。
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>
答案 2 :(得分:2)
我更新了你的插件构造函数。注意变量Pulsate.possiblePlaces
,我已经通过这种方式更改了变量声明,以便能够为插件的所有Object实例共享变量数据。
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,
}
];
};
我将occupied
属性添加到可能的位置以识别已经占用的属性。如果randomed currentPlace
已被占用,请再次搜索随机位置。
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();
}
};
每次隐藏元素时,请将occupied
属性设置为false
。
Pulsate.prototype.animateToZero = function() {
var self = this;
self.element.animate({
'fontSize': 0,
'queue': true
}, self.speed, function() {
self.currentPlace.occupied = false;
self.defineRandomPlace();
});
};
答案 3 :(得分:2)
小提示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