fgnass / spin.js

A spinning activity indicator
http://spin.js.org
MIT License
9.3k stars 1.02k forks source link

Animated in wkwebview does not rotate #365

Closed HookTong closed 3 years ago

HookTong commented 5 years ago

under certain circumstances,Animated in wkwebview does not rotate

benmcmaster commented 5 years ago

I am having this issue as well using wkwebview on iOS 12.1.2 . I noticed that when I quit my cordova app fully and then bring it back, it will rotate normally. However, if I put the app into the background, and then bring it back, the spinner won't rotate. You just see the background of the spinner doing nothing... Really weird. I just upgraded to the latest and still the same bug. Same issue with and without hwaccel. Any ideas of what we can try?

theodorejb commented 5 years ago

Does the issue occur with spin.js 3.1? Versions 2.x and 4.0 use CSS keyframe animations, while 3.x uses requestAnimationFrame.

You could also try adding your own infinite CSS animation and see if that exhibits the same issue. If so, this is likely a limitation/bug in iOS or Cordova rather than a problem specific to spin.js.

HookTong commented 5 years ago

Yes, I am using the 3.x version. After the app is switched back from the background to the foreground in wkwebview, the animation will not rotate. However, I solved the problem after rewriting the rotation animation myself; the following is my code: css : @keyframes lds-spinner { 0% { opacity: 1; } 100% { opacity: 0; } }

@-webkit-keyframes lds-spinner { 0% { opacity: 1; } 100% { opacity: 0; } } function Spinner(opts) { var obj = null; var optsObj = opts; var defOpts = { color: "#FFFFFF", petalRadius: 5, internalRadius: 14, petalSum: 10, }; this.spin = spin; this.stop = stop; function spin(target) { stop(); if (target == null) { return; } var color; var petalRadius; var internalRadius; var petalSum; if (optsObj != null) { color = optsObj["color"]; if (color == null) { colro = "#FFFFFF"; } petalRadius = optsObj["petalRadius"]; if (petalRadius == null || isNaN(petalRadius)) { petalRadius = 5; } internalRadius = optsObj["internalRadius"]; if (internalRadius == null || isNaN(internalRadius)) { internalRadius = 14; } petalSum = optsObj["petalSum"]; if (petalSum == null || isNaN(petalSum)) { petalSum = 10; } } else { color = defOpts["color"]; petalRadius = defOpts["petalRadius"]; internalRadius = defOpts["internalRadius"]; petalSum = defOpts["petalSum"]; } var id = $(target).attr("id"); console.log("spin target id:" + id); var root = "<div id=\"" + id + "_spin_root\">[content]

"; var run = "<div class=\"lds-spinner\">[content]
"; var viewPetal = "
"; var viewPetals = ""; for (var i = 0; i < petalSum; i++) { viewPetals += viewPetal; } run = run.replace("[content]", viewPetals); root = root.replace("[content]", run); $(target).html(root); obj = $("#" + id + "_spin_root"); obj.css({ "display": "flex", "justify-content": "center", "align-items": "center", "width": "100%", "height": "auto", "box-sizing": "border-box" }); var rW = (petalRadius 2 + internalRadius) 2; var rH = (petalRadius 2 + internalRadius) 2; var pW = petalRadius 2; var pH = petalRadius 2; var pTop = (rH - pH) / 2; var xOffset = (rW / 2); var yOffset = (rH / 2) - pTop; var originTran = xOffset + "px " + yOffset + "px"; console.log("originTran:" + originTran); console.log("rW:" + rW + ",rH:" + rH + ",pW:" + pW + ",pH:" + pH + ",pTop:" + pTop + ",xOffset:" + xOffset + ",yOffset:" + yOffset); $(".lds-spinner").css({ "position": "relative", "width": rW + "px", "height": rH + "px" }); $(".lds-spinner div").css({ "left": "0px", "top": pTop + "px", "position": "absolute", "width": pW + "px", "height": pH + "px", "border-radius": "50%", "background": color, "transform-origin": originTran, "-webkit-transform-origin": originTran }); var rotateIncrement = 360 / petalSum; console.log("spin rotateIncrement:" + rotateIncrement); var timeIncrement = 1 / petalSum; console.log("spin timeIncrement:" + timeIncrement); for (var i = 0; i < petalSum; i++) { var index = i + 1; var deg = (rotateIncrement index) - rotateIncrement; var time = (timeIncrement index) - 1; time = time.toFixed(2); console.log("deg:" + deg + ",deg time:" + time); $(".lds-spinner div:nth-child(" + index + ")").css({ "transform": "rotate(" + deg + "deg)", "-webkit-transform": "rotate(" + deg + "deg)", "animation": "lds-spinner linear 1s infinite", "-webkit-animation": "lds-spinner linear 1s infinite", "animation-delay": time + "s", "-webkit-animation-delay": time + "s" }); } } function stop() { if (obj != null) { obj.remove(); obj = null; console.log("spinLoading stop"); } } }

benmcmaster commented 4 years ago

@theodorejb Oh man, I am using a very old version. It doesn't even have a version. Just: Copyright (c) 2011-2013 Felix Gnass. I am also using the jquery.spin.js as well. This is for an old project started in 2013... I have this spinner everywhere. I really don't want to refactor. Can you think of anything I could try to fix it?

benmcmaster commented 4 years ago

@fgnass @theodorejb I am looking to upgrade to the latest https://spin.js.org/spin.umd.js, but I would love to use the old jquery.spin.js interface...

Any thoughts on how I might modify the old jquery interface to work with the new spin.umd.js? After just replacing the old spin.js with the code from spin.umd.js now its throwing an error: Error: Spin.js not present.

/**
 * Copyright (c) 2011-2013 Felix Gnass
 * Licensed under the MIT license
 */

/*

Basic Usage:
============

$('#el').spin(); // Creates a default Spinner using the text color of #el.
$('#el').spin({ ... }); // Creates a Spinner using the provided options.

$('#el').spin(false); // Stops and removes the spinner.

Using Presets:
==============

$('#el').spin('small'); // Creates a 'small' Spinner using the text color of #el.
$('#el').spin('large', '#fff'); // Creates a 'large' white Spinner.

Adding a custom preset:
=======================

$.fn.spin.presets.flower = {
  lines: 9
  length: 10
  width: 20
  radius: 0
}

$('#el').spin('flower', 'red');

*/

(function(factory) {

  if (typeof exports == 'object') {
    // CommonJS
    factory(require('jquery'), require('spin'))
  }
  else if (typeof define == 'function' && define.amd) {
    // AMD, register as anonymous module
    define(['jquery', 'spin'], factory)
  }
  else {
    // Browser globals
    if (!window.Spinner) throw new Error('Spin.js not present')
    factory(window.jQuery, window.Spinner)
  }

}(function($, Spinner) {

  $.fn.spin = function(opts, color) {

    return this.each(function() {
      var $this = $(this),
        data = $this.data();

      if (data.spinner) {
        data.spinner.stop();
        delete data.spinner;
      }
      if (opts !== false) {
        opts = $.extend(
          { color: color || $this.css('color') },
          $.fn.spin.presets[opts] || opts
        )
        data.spinner = new Spinner(opts).spin(this)
      }
    })
  }

  $.fn.spin.presets = {
    tiny: { lines: 8, length: 2, width: 2, radius: 3 },
    small: { lines: 8, length: 4, width: 3, radius: 5 },
    large: { lines: 10, length: 8, width: 4, radius: 8 }
  }

}));
theodorejb commented 4 years ago

@benmcmaster I think you would have to replace window.Spinner with window.Spin.Spinner.

benmcmaster commented 4 years ago

@theodorejb Ah cool. Thanks! I actually ended up just setting window.Spinner = Spinnerin spin.js and everything worked perfectly.