Safari中无法调整particle-slider标志大小

3
我正在使用HTML 5 Blank Child Theme从WordPress加载一个前端站点。我有一个使用Particle Slider的标志效果,当屏幕大小>960px时,对于< 960px的屏幕尺寸,我有一个平面徽标图像。在Firefox和Google Chrome上都可以正常工作,但是在Safari上调整徽标大小时,必须手动刷新页面(即按cmd+r),才能再次显示PS效果。该代码源自我在这里发布的原始问题-Original Stack Q&A 以下是我现在使用的javascript代码- particle-slider.php
<?php /* Template Name: particle-slider */ ?>
<!-- particle-slider template -->

    <div id="particle-slider">
        <div class="slides">
            <div class="slide" data-src="<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logohight.png"></div>
        </div>
        <canvas class="draw" style="width: 100%; height: 100%;"></canvas>
     </div>
     <script type="text/javascript">
        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;
        });
    </script>
  <div id="logo"> <img src="<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logo.png"> </div>

  <!-- particle-slider template -->

我需要和这个网站这里看到的一样的效果——当页面被重新调整大小时,标志从粒子变为静态。粒子标志完美地重新出现。
所有其他相关代码都与原始问题链接在一起,因为没有任何改变。我没有看到控制台中有任何提示为什么它不起作用。
2个回答

2
resize事件可能会触发多次,在该事件中,你放置在setTimeout中的任何内容都将在当前代码块执行后调用。没有仔细分析ParticleSlider,很难确定原因,但我认为全局变量(nextFrameCalled, oldWidth)和回调函数不按预期顺序触发是原因。
我认为意图是要“防抖”强制重启-你想调用ParticleSlider.nextFrame(),但如果它已经被调用,你需要等待100毫秒。
查看你为此问题适应的答案,似乎这是canvas元素在requestAnimationFrame上不可见的解决方法-在100ms或ParticleSlider.nextFrame()被多次调用尝试触发之后,可能仍然不可用。
从你的原始问题和选择的答案中,我认为你需要ParticleSlider.init()来重置组件,但闪烁是由于每次运行时需要一段时间。 ParticleSlider.nextFrame()不需要太长时间(并使用requestAnimationFrame避免了jank),但在Safari中不会在调整大小时创建canvas
因此,修复方法如下:
  1. 使用ParticleSlider.init()
  2. 防抖动调整大小事件,以便不会多次触发它
  3. 用户停止触发调整大小事件后短暂延迟后仅触发一次。
代码将类似于:
var timeout = null;
window.addEventListener('resize', function() {
    // Clear any existing debounced re-init
    clearTimeout(timeout);

    // Set up a re-init to fire in 1/2 a secound
    timeout = setTimeout(function() {
        ps.init();
    }, 500);
});

您仍然会看到组件重新初始化时的闪烁和延迟,但只会发生一次。

我想补充说明的是,ParticleSlider已被作者弃用,并被NextParticle替代 - 可能是为了解决这些问题(实际上它具有特定的功能来处理调整大小)。由于这是一个付费组件,我建议向他们寻求帮助,因为您应该得到物有所值的回报(或切换到开源组件,在那里您可以自己修复这些错误)。


谢谢您,那么我将这段代码插入到我选择的答案中?我需要替换一些现有的代码吗?我对js不是很熟悉,所以如果我听起来有点幼稚,请原谅。实际上,由于图像一直闪烁不定,我放弃了我的选择答案并选择了下面的答案,但正如我所说,它在Safari中无法工作。如果我可以使用这个代码修复它,我会重新实施它。 - Mike.Whitehead
这个网站http://teamgeek.co.za/使用了相同的粒子设计和相同的重新调整大小事件(将粒子变为手机/平板电脑的静态标志),并且它可以完美地重新调整大小。我需要能够重新创建这种效果。 - Mike.Whitehead
@Mike.Whitehead 不完全是,它更像是大部分的替代品。我没有在你原来的答案中实现IE8支持。那个teamgeek网站仍然相当不稳定(即使在我的相当不错的开发机器上),所以如果那是你的理想,你可能需要考虑到卡顿和丢帧。他们的实现看起来与你的完全不同 - 特别是他们调用ParticleSlider.resize(),这反过来又调用了init - 就像你在之前的问题中最初选择的答案一样,而不是你在这里复制的备选答案。 - Keith
@Mike.Whitehead ParticleSlider 是付费的,这意味着您应该从编写它的人那里获得一些专门的支持(如果您没有得到支持,则不要使用它)。这可能比尝试反向工程 teamgeek 的 Angular 实现更容易。 - Keith
我又尝试了一遍你的代码,但在这个实例中它仍然无法工作。 - Mike.Whitehead
显示剩余2条评论

1

所以,我通过重新追溯之前的问答,终于弄清楚了这个问题。之前似乎有一些示例链接存在问题,但现在有一个可以使用 - example

我进入页面检查器,注意到这个示例代码和实际答案中的代码之间有一些差异,这是导致标志像灯泡一样闪烁的原因。这是我现在放入WordPress网站中的代码 -

<script type="text/javascript">
        //wait until the DOM is ready to be queried
        (function() {//document.addEventListener('DOMContentLoaded', function() { //DOM-ready callback
            var ps, timeout;
            var img1 = new Image();
            img1.src = '<?php echo home_url(); ?>/wp-content/uploads/2017/10/havoc_logohight.png';//havoc_logo_e6os2n.png';
            var imgs = [ img1 ];
            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 (ps != undefined && typeof ps !== null) {
                        ps.init(); //refresh the particle slider since it exists
                        console.log('called init on ps');
                    } else {
                            if (window.location.search.indexOf('d=1') > -1) {
                                    debugger;
                            }
                        //otherwise create a new instance of the particle slider
                        ps = new ParticleSlider({
                            width: 1400, 
                            height: 600,
                            imgs: imgs
                        });
                    }
                }
                else {
                    //when the flat logo is displayed, get rid of the particle slider instance
                 //   delete ps;
                    ps = null;
                }
            }
        })();
    </script>

现在它在所有主要浏览器中都可以良好运行 - Chrome/Safari/Firefox。当其重新调整大小时,它仍然感觉有些笨拙,因为它会将页面的其余部分向下推动,并且它可能需要比我想象中多几秒钟 - 不确定是否有定时器选项来加速重新动画?否则,一切正常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接