【问题标题】:particle-slider logo won't resize in Safari粒子滑块徽标不会在 Safari 中调整大小
【发布时间】:2018-05-19 05:28:58
【问题描述】:

我正在使用 HTML 5 空白子主题从 Wordpress 加载前端站点。当我的屏幕尺寸大于 960 像素时,我使用粒子滑块产生徽标效果;对于 cmd+r) PS效果再次显现。代码来自我在这里发布的一个原始问题 - Original Stack Q&A

这是我现在使用的 javascript 代码 -

粒子滑块.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 -->

我需要与在此站点here 上看到的效果相同的效果 - 当页面重新调整大小时,徽标会从粒子切换到静态。粒子标志完美再现。

所有其他相关代码都链接到原始问题,因为没有任何改变。我在控制台中没有看到任何提示它为什么不起作用的东西。

【问题讨论】:

    标签: javascript wordpress safari cross-browser


    【解决方案1】:

    resize 事件可以触发多次,在该事件中,您放入 setTimeout 的任何内容都将在当前代码块执行后被调用。如果不拆开ParticleSlider,就很难确定,但我认为全局变量(nextFrameCalledoldWidth)和按预期顺序触发的回调是原因。

    我认为目的是去抖动强制重启 - 你想调用 ParticleSlider.nextFrame() 但如果它已经被调用,你想先等待 100 毫秒。

    查看answer you've adapted 这个问题似乎是canvas 元素在requestAnimationFrame 上不可见的解决方法 - 在 100 毫秒或 ParticleSlider.nextFrame() 被称为多个之后可能仍然不可用次试图让它开火。

    根据您的原始问题和selected answer,我认为您需要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 中工作。如果我可以使用此代码修复它,我将重新实现它。
    • 该网站teamgeek.co.za 使用相同的粒子设计和相同的重新调整大小事件(手机/平板电脑的粒子到静态徽标),并且可以完美调整大小。我需要能够重新创建这种效果。
    • @Mike.Whitehead 不是真的,它更像是大部分内容的替代品。我没有为您原始答案中实现的 IE8 支持而烦恼。那个 teamgeek 网站仍然很笨拙(即使在我相当不错的开发机器上),所以如果这是你的理想,你可能需要考虑口吃和丢帧。他们的实现看起来不像你的 - 特别是他们调用ParticleSlider.resize(),而后者又调用init - 就像你最初选择的上一个问题的答案,而不是你在这里复制的替代答案。
    • @Mike.Whitehead ParticleSlider 是付费的,这意味着你应该从编写它的人那里得到一些专门的支持(如果你没有得到,那就不要使用它)。这可能比尝试对 teamgeek 的 Angular 实现进行逆向工程更容易。
    • 我再次尝试了您的代码,但它在这种情况下不起作用。
    【解决方案2】:

    所以,我终于通过使用之前的 Q&A 追溯我的步骤来解决这个问题。以前,一些示例链接似乎存在问题,但现在似乎可以使用 - 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 上正常运行。它仍然感觉有点笨拙,因为它在重新调整大小时将页面的其余部分向下推,并且可能比我想要的多几秒钟 - 不确定是否有一个计时器选项可以加快恢复速度?否则,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-06
      • 2023-03-03
      • 1970-01-01
      • 2021-09-21
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      相关资源
      最近更新 更多