I\'m loading a front-end site from Wordpress using a HTML 5 Blank Child Theme. I have a logo effect using particle slider for when I have a screen size of >960px; for screen
replace this code:
<script type="text/javascript">
var ps = new ParticleSlider({ 'width':'1400', 'height': '600' });
</script>
with this code:
<script type="text/javascript">
//wait until the DOM is ready to be queried
document.addEventListener('DOMContentLoaded', function() { //DOM-ready callback
var ps, timeout;
handlePS();
window.addEventListener('resize', function() {
if (timeout) { //check if the timer has been set
clearTimeout(timeout); //clear the timer
}
//set a timer
timeout = setTimeout(handlePS, 250);
});
function handlePS() {
if (document.body.clientWidth >= 960) {
//check if ps is assigned as an instance of the ParticleSlider
if (window.ps && typeof ps !== null) {
ps.init(); //refresh the particle slider since it exists
} else {
//otherwise create a new instance of the particle slider
ps = new ParticleSlider({
'width': '1400',
'height': '600'
});
}
}
else {
//when the flat logo is displayed, get rid of the particle slider instance
ps = null;
}
}
});
</script>
One can add a callback for when the resize event occurs (as others have mentioned) and call the init() method depending on the current width of the window.
It might be advisable to move the code that creates the Particle Slider instance
to a function, which checks if the width of the window is greater than or equal to 960 pixels (using .clientWidth of document.body) and if so, if the instance has been created or not using a variable ps
declared outside the function. If the instance has been created, call the init method; Otherwise create the instance. But if the width is less than 960 pixels then set the variable ps
to null
.
var ps; //declare out here for use in multiple functions
function handlePS() {
if (document.body.clientWidth > 960) {
if (window.ps && typeof ps !== null) {
ps.init();
} else {
ps = new ParticleSlider({'width': '1400', 'height': '600'});
}
}
else {
ps = null;
}
}
Then that function can be called when the page loads as well as when the resize event occurs:
handlePS();
window.addEventListener('resize', handlePS);
See a demonstration in this sample page. There are a few other enhancements added:
handlePS()
and listening for the resize event after the DOMContentLoaded event has been fired by using document.addEventListenerinit()
method is called 250ms after the scroll event ends instead of continuously during a scroll event.So the code with those enhancements looks like below:
//wait until the DOM is ready to be queried
document.addEventListener('DOMContentLoaded', function() { //DOM-ready callback
var ps, timeout;
handlePS();
window.addEventListener('resize', function() {
//https://davidwalsh.name/javascript-debounce-function
if (timeout) { //check if the timer has been set
clearTimeout(timeout); //clear the timer
}
//set a timer
timeout = setTimeout(handlePS, 250);
});
function handlePS() {
if (document.body.clientWidth >= 960) {
//check if ps is assigned as an instance of the ParticleSlider
if (window.ps && typeof ps !== null) {
ps.init(); //refresh the particle slider since it exists
} else {
//otherwise create a new instance of the particle slider
ps = new ParticleSlider({
'width': '1400',
'height': '600'
});
}
}
else {
//when the flat logo is displayed, get rid of the particle slider instance
ps = null;
}
}
});
And because you added the jquery tag, jQuery could be used to simplify things a bit:
instead of
window.addEventListener('resize', handlePS);
use:
$(window).on('resize, handlePS);
And replace document.body.clientWidth
width $(document).width()
.
I used the image from your comment in the updated sample page. I also pared down the code used on the Particle Slider demo page and added in that image on this demo page. It still suffers from flashing when there is a resize.
Update (30 Oct 2017)
So the issue appeared to be the fact that since you hide the div
that is used by ParticleSlider
for drawing, it gets Canvas
with size 0x0 and this leads to an exception somewhere inside drawParticles
method which is called by nextFrame
. Another important fact is that ParticleSlider
is designed in such a way that after the first call initiated from constructor, nextFrame
uses requestAnimationFrame
to schedule itself. All other methods (such as nextSlide
or resize
) just change data but do not re-start animation sequence. Thus exception at the first call stops animation and to fix it, you need to call nextFrame
explicitly.
So the basic idea is that you patch nextFrame
to track failure/success and call it from resize handler if needed. Here is some code:
var ps = new ParticleSlider({ 'width': '1400', 'height': '600' });
// patch nextFrame to track failure/success
var nextFrameCalled = false;
ps.oldNextFrame = ps.nextFrame;
ps.nextFrame = function () {
try {
ps.oldNextFrame.apply(this, arguments);
nextFrameCalled = true;
} catch (e) {
console.log(e);
nextFrameCalled = false;
}
};
var addEvent = function (object, type, callback) {
if (object.addEventListener) {
object.addEventListener(type, callback, false);
} else if (object.attachEvent) {
object.attachEvent("on" + type, callback);
} else {
object["on" + type] = callback;
}
};
var oldWidth = window.innerWidth;
addEvent(window, 'resize', function () {
var newWidth = window.innerWidth;
if (newWidth >= 960 && oldWidth < 960) {
console.log("Restarting particle slider " + newWidth);
ps.resize();
if (!nextFrameCalled)
ps.nextFrame(); // force restart animation
else {
// ensure that nextFrameCalled is not still true from previous cycle
nextFrameCalled = false;
setTimeout(function () {
if (!nextFrameCalled)
ps.nextFrame(); // force restart animation
}, 100);
}
}
oldWidth = newWidth;
});
You can see live demo at this plunker. Open demo in a separate window. Then you'll have 2 seconds to set initial size more or less than 960px so you can simulate any starting conditions. After 2 seconds timeout the main code starts.
Original answer
It looks like you lack a piece of code that would re-shuffle particles when window size is changed to >960px. I haven't tried it, but I expect that something like this should help you (if you use jQuery):
var ps = new ParticleSlider({ 'width': '1400', 'height': '600' });
var oldWidth = $(window).width();
$(window).resize(function () {
var newWidth = $(window).width();
if (newWidth >= 960 && oldWidth < 960)
ps.resize(); // this should call init() which in turn should re-shuffle particles
oldWidth = newWidth;
});
Obviously you can write an equivalent code without jQuery for example as suggested in this SO answer
Your use case has two major issues:
I tried to handle both issues in the following script.
var ps = null
function init(){
var isVisible = window.innerWidth >= 960;
if (!ps && isVisible) {
// create and init
ps = new ParticleSlider({
ptlGap: 1,
ptlSize: 1,
width: 1e9,
height: 100,
});
ps.init(false);
} else if (ps && !isVisible) {
// stop and remove
ps.requestAnimationFrame = function() {}; // Stop render loop
ps = null;
}
}
window.addEventListener('load', init, false)
window.onload = init;
window.addEventListener('resize', init, false);
window.onresize = init;
html, body {
background-color: black;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
color: #fff;
text-align: center;
}
.slides, & > .dg {
display: none;
}
.low-res {
display: none;
}
@media screen and (max-width: 959px) {
.draw {
display: none;
}
.low-res {
display: inline;
width: 50%;
}
}
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>ParticleSlider</title>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/23500/ps-0.9.js"></script>
</head>
<body id="particle-slider">
<div class="slides">
<div id="first-slide" class="slide" data-src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGkAAAAgCAMAAAAmC6asAAAAMFBMVEX19vf19vft7u/19vfp6uv19vfx8vP19vf19vf19vf19vfm5+j19vcAAAD19vfl5udu+MchAAAADnRSTlOIVcIz10StZneZEewiAMEzGswAAAF/SURBVHja7ZXZbsQwCEXjneXa/P/fFntm0uRpVGkaqVX8YAW4cMCxkq1ftW7STbpJP1sJb0lFPkJiekuq4TMkfkti+gxpe0uivRmB9LQOlHraNixnYErPONAfcYZntYfv9aDtJTmUO5OCeukGR5paqZtbGaSVzYWIlZ9DI6vVpC6shJw5TzdlZk47qZpldAkteBVToxNJrLGqoil6MPE9A1bSNorUXPYWvbLUjbg37lwRNPYW6x6eJK4ilB2hVmChJw2nWx4He3Map1exMVFvQyMVN78rlexbY7Gk0tWUm7gsHUnikQ6dwzLRLM/tRKIlGMMFoijmpthqBocLFTLWO41GnhrFXZIGTiTz5pIyA9G4uqSeSV3W4bSsqvycg0x9RTpcKHaHHybNOZBXfPa41jNjLCeqjRopzgI4kXYcsDqVZWJaZwVWHpYBTOuoACCvEpjTC3DFd6/oVV9YmPw+CWsb+H1SxVWkkgkoV5B6ijasXnMjBPIf/u436e+TvgDCaqPX6lO5yQAAAABJRU5ErkJggg==">
</div>
</div>
<canvas class="draw"></canvas>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/23500/codepen-white.png" class="low-res"/>
</body>
</html>
You can use the resize function of ParticleSlider in jquery smart resize. So you will have more control on the function.
var ps = new ParticleSlider({ 'width': '1400', 'height': '600' });
$(window).on("debouncedresize", function( event ) {
ps.resize();
});
The Problem is the following: The slider draws with js into the canvas, seems like the script is loaded once on page load... The slider shall be responsive as the athors say on their site, but in fact the slider is just resized and not replayed on window resize...
To me it seems like calling
ps.nextSlide(0);
on $(window).resize() could help. This reloads the current slide!
If this does not work too, try to reload the whole slider with the init() function or maybe the loadingStep() function! (The documentation is sadly not that clear to me at some points...)
i.e.:
$(window).resize(function(){
ps.nextSlide(0);
});
You can see the functions availeble here:
http://particleslider.com/documentation/reference