PIXI js 水滴动画在每个涟漪事件上加速
PIXI js water drop animation speeding up on each ripple event
第一次使用 PixiJS 并希望为我的网页创建一个背景,用户可以点击它并且水波纹出现在点击的中心,从那里扩展 co-centrically。
它在第一次点击时完美运行,但随后点击“co-centric 展开”动画速度加快,所以点击 5 时它真的很快。
我找不到如何保持相同的速度。此外,注意到随着波纹从页面上消失,代码运行的迭代次数多于需要的次数。感谢您的帮助!
这是我的代码(抱歉太长了):
HTML / Blade 模板:
<div
id="water-ripples"
class="relative bg-cover h-vhscreen flex flex-col justify-center py-12 sm:px-6 lg:px-8"
style="background-image: url({{ env('AWS_STATIC_BUCKET_URL') . '/images/water.jpg' }});"
>
@yield('content')
</div>
Javascript:
import * as PIXI from 'pixi.js'
window.moment = require('moment');
/**
* Set up last code to run when page assembled
*/
let app = null
let stage = null
let renderer = null
let ripples = []
let sprite = null
$(document).ready(function() {
app = new PIXI.Application({
antialias: true,
transparent: true,
resolution: 1,
})
// setup ticker
let ticker = new PIXI.Ticker();
ticker.add(() => {
renderer.render(stage);
}, PIXI.UPDATE_PRIORITY.LOW);
ticker.start();
renderer = app.renderer
renderer.autoResize = true
renderer.view.style.position = "fixed";
renderer.view.style.top = 0;
renderer.view.style.left = 0;
renderer.view.style.zIndex = 1;
renderer.view.style.display = "block";
renderer.autoResize = true
renderer.resize(window.innerWidth, window.innerHeight);
ripples = [];
stage = app.stage;
stage.interactive = true
document.getElementById('water-ripples').appendChild(app.renderer.view)
// load assets
let resources = {
waterRippleImage: aws_static_bucket_url + '/images/water.jpg',
waterRippleMap: aws_static_bucket_url + '/images/water_map.png',
};
Object.keys(resources).forEach(k => {
app.loader.add(k, resources[k])
})
app.loader.load(setup);
ticker.add(function(delta) {
for(var i = 0; i < ripples.length; i++) {
ripples[i].update();
}
});
});
function setup() {
// background
let bg = new PIXI.Sprite(app.loader.resources.waterRippleImage.texture);
bg.anchor.set(0.5);
bg.scale.set(0.9);
bg.position.set(renderer.view.width / 2, renderer.view.height / 2);
stage.addChild(bg);
// add new ripple each time mouse is clicked
renderer.view.addEventListener('mousedown', ev => {
ripples.push(new Ripple(ev.clientX, ev.clientY));
stage.filters = ripples.map(function(f) { return f.filter; });
}, false);
// add new ripple each time screen is touched
renderer.view.addEventListener('touchstart', ev => {
ripples.push(new Ripple(ev.clientX, ev.clientY));
stage.filters = ripples.map(function(f) { return f.filter; });
}, false);
window.addEventListener('resize', () => {
app.renderer.resize(window.innerWidth, window.innerHeight);
bg.position.set(renderer.view.width / 2, renderer.view.height / 2);
})
window.addEventListener('focus', () => {
// Clear Out Old Ripples
ripples = ripples.filter(r => {
return (moment.now() - 1000) < r.startTime
})
})
window.addEventListener('blur', () => {
// Clear Out Old Ripples
ripples = ripples.filter(r => {
return (moment.now() - 1000) < r.startTime
})
})
}
function Ripple(x, y) {
// sprite
sprite = new PIXI.Sprite(app.loader.resources.waterRippleMap.texture);
sprite.anchor.set(0.5);
sprite.position.set(x, y);
sprite.scale.set(0.1);
stage.addChild(sprite);
// filter
this.filter = new PIXI.filters.DisplacementFilter(sprite);
this.startTime = moment.now()
}
Ripple.prototype.update = function() {
sprite.scale.x += 0.025;
sprite.scale.y += 0.025;
}
我认为您在 Ripple class 中的精灵是问题所在。它应该分配给 this.sprite
,而不是全局变量 sprite。实际上,当您遍历涟漪时,您将比例递增 N 次,其中 N 是涟漪的数量。
第一次使用 PixiJS 并希望为我的网页创建一个背景,用户可以点击它并且水波纹出现在点击的中心,从那里扩展 co-centrically。
它在第一次点击时完美运行,但随后点击“co-centric 展开”动画速度加快,所以点击 5 时它真的很快。
我找不到如何保持相同的速度。此外,注意到随着波纹从页面上消失,代码运行的迭代次数多于需要的次数。感谢您的帮助!
这是我的代码(抱歉太长了):
HTML / Blade 模板:
<div
id="water-ripples"
class="relative bg-cover h-vhscreen flex flex-col justify-center py-12 sm:px-6 lg:px-8"
style="background-image: url({{ env('AWS_STATIC_BUCKET_URL') . '/images/water.jpg' }});"
>
@yield('content')
</div>
Javascript:
import * as PIXI from 'pixi.js'
window.moment = require('moment');
/**
* Set up last code to run when page assembled
*/
let app = null
let stage = null
let renderer = null
let ripples = []
let sprite = null
$(document).ready(function() {
app = new PIXI.Application({
antialias: true,
transparent: true,
resolution: 1,
})
// setup ticker
let ticker = new PIXI.Ticker();
ticker.add(() => {
renderer.render(stage);
}, PIXI.UPDATE_PRIORITY.LOW);
ticker.start();
renderer = app.renderer
renderer.autoResize = true
renderer.view.style.position = "fixed";
renderer.view.style.top = 0;
renderer.view.style.left = 0;
renderer.view.style.zIndex = 1;
renderer.view.style.display = "block";
renderer.autoResize = true
renderer.resize(window.innerWidth, window.innerHeight);
ripples = [];
stage = app.stage;
stage.interactive = true
document.getElementById('water-ripples').appendChild(app.renderer.view)
// load assets
let resources = {
waterRippleImage: aws_static_bucket_url + '/images/water.jpg',
waterRippleMap: aws_static_bucket_url + '/images/water_map.png',
};
Object.keys(resources).forEach(k => {
app.loader.add(k, resources[k])
})
app.loader.load(setup);
ticker.add(function(delta) {
for(var i = 0; i < ripples.length; i++) {
ripples[i].update();
}
});
});
function setup() {
// background
let bg = new PIXI.Sprite(app.loader.resources.waterRippleImage.texture);
bg.anchor.set(0.5);
bg.scale.set(0.9);
bg.position.set(renderer.view.width / 2, renderer.view.height / 2);
stage.addChild(bg);
// add new ripple each time mouse is clicked
renderer.view.addEventListener('mousedown', ev => {
ripples.push(new Ripple(ev.clientX, ev.clientY));
stage.filters = ripples.map(function(f) { return f.filter; });
}, false);
// add new ripple each time screen is touched
renderer.view.addEventListener('touchstart', ev => {
ripples.push(new Ripple(ev.clientX, ev.clientY));
stage.filters = ripples.map(function(f) { return f.filter; });
}, false);
window.addEventListener('resize', () => {
app.renderer.resize(window.innerWidth, window.innerHeight);
bg.position.set(renderer.view.width / 2, renderer.view.height / 2);
})
window.addEventListener('focus', () => {
// Clear Out Old Ripples
ripples = ripples.filter(r => {
return (moment.now() - 1000) < r.startTime
})
})
window.addEventListener('blur', () => {
// Clear Out Old Ripples
ripples = ripples.filter(r => {
return (moment.now() - 1000) < r.startTime
})
})
}
function Ripple(x, y) {
// sprite
sprite = new PIXI.Sprite(app.loader.resources.waterRippleMap.texture);
sprite.anchor.set(0.5);
sprite.position.set(x, y);
sprite.scale.set(0.1);
stage.addChild(sprite);
// filter
this.filter = new PIXI.filters.DisplacementFilter(sprite);
this.startTime = moment.now()
}
Ripple.prototype.update = function() {
sprite.scale.x += 0.025;
sprite.scale.y += 0.025;
}
我认为您在 Ripple class 中的精灵是问题所在。它应该分配给 this.sprite
,而不是全局变量 sprite。实际上,当您遍历涟漪时,您将比例递增 N 次,其中 N 是涟漪的数量。