【问题标题】:how to stop and start AMcharts globe animation with intersectionObserver?如何使用intersectionObserver 停止和启动AMcharts 地球动画?
【发布时间】:2022-10-20 17:59:30
【问题描述】:

我的网站首页上有来自 AMcharts 的旋转地球动画。但它会占用大量系统资源,即使它滚动到屏幕外,添加到站点的任何更多动画按钮都会使 chrome 爬行速度变慢。在过去的几天里,我对如何停止和启动 three.js 动画和画布动画进行了一些研究,并发现了交叉点观察者,我从找到的地方复制并粘贴了一些代码并添加了它在中,似乎我仍然缺少 AMcharts 中的实际停止和启动功能,intersectionobserver 可以在与 id="status" 与我的 div 相交时挂钩以控制动画

我研究了 AMcharts 文档,但我无法理解,amcharts 中是否有停止和启动或暂停功能?

/**
 * ---------------------------------------
 * This demo was created using amCharts 4.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v4/
 * ---------------------------------------
 */

// Themes begin

am4core.useTheme(am4themes_animated);
// Themes end
am4core.options.queue = true;
am4core.options.onlyShowOnViewport = true;
var chart = am4core.create("chartdiv", am4maps.MapChart);

// Set map definition
chart.geodata = am4geodata_worldLow;

// Set projection
chart.projection = new am4maps.projections.Orthographic();
chart.panBehavior = "none";
chart.deltaLatitude = -20;
chart.padding(20,20,20,20);

// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());

// Make map load polygon (like country names) data from GeoJSON
polygonSeries.useGeodata = true;
//polygonSeries.include = ["BR", "UA", "MX", "CI"];

// Configure series
var polygonTemplate = polygonSeries.mapPolygons.template;

polygonTemplate.fill = am4core.color("#d5ebfe");
polygonTemplate.stroke = am4core.color("#fff");
polygonTemplate.strokeWidth = 0.0;



var graticuleSeries = chart.series.push(new am4maps.GraticuleSeries());
graticuleSeries.mapLines.template.line.stroke = am4core.color("#00000");
graticuleSeries.mapLines.template.line.strokeOpacity = 0.00;
graticuleSeries.fitExtent = false;

chart.maxZoomLevel = 1;
chart.backgroundSeries.mapPolygons.template.polygon.fillOpacity = 0.0;
chart.backgroundSeries.mapPolygons.template.polygon.fill = am4core.color("#ffffff");

// Create hover state and set alternative fill color

let animation;
setTimeout(function(){
  animation = chart.animate({property:"deltaLongitude", to:100000}, 20000000);
}, 3000)

chart.seriesContainer.events.on("down", function(){
//  animation.stop();
})



////////////////My added intersectionObserver code////////

function start() {
  create();
}

// stop render
function stop() {
 window.cancelAnimationFrame(requestId);
 requestId = undefined;
}

const statusElem = document.querySelector('.status');

const onScreen = new Set();
const intersectionObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      onScreen.add(entry.target);
      start();
      console.log('render has been started');
    } else {
      onScreen.delete(entry.target);
      stop();
      console.log('render has been halted');
        }     
  });
  statusElem.textContent = onScreen.size
    ? `on screen: ${[...onScreen].map(e => e.textContent).join(', ')}`
    : 'none';
});

document.querySelectorAll('#chartdiv').forEach(elem => intersectionObserver.observe(elem));
.status {
    position: fixed;
    background: rgba(0,0,0,0.8);
    color: white;
    padding: 1em;
    font-size: medium;
    top: 50%;
    left: 0;
    z-index: 998;
  }
  
  #header{
    position:fixed;
    top: 0px;
    right:0px;
    z-index: 998;
    height: 5em;
    width: 100%;
    background-color: white;
    opacity: 80%;
 }
 
  #chartdiv {
    width: 100%;
    height: 20em;
  max-width:100%;
  
  }
  #section0{
    background-image: linear-gradient(128deg,#340191,#000);
  height: 300vh;
}
<body>
 
  <script src="https://www.amcharts.com/lib/4/core.js"></script>
  <script src="https://www.amcharts.com/lib/4/maps.js"></script>
  <script src="https://www.amcharts.com/lib/4/geodata/worldLow.js"></script>
  <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
  
  <div class="status"></div>

  <header id="header">
    
    
    
  </header>

  <div class="status">status</div>

  
 
   
    <div class="section" id="section0">
      <div class="intro">
        
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div id="chartdiv"></div>
        <script src="js/globe.js"></script>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        
      </div>
      
    </div>

   
    
</body>

有最小的可复制示例。当#status 与#chartdiv 相交时,动画应该运行,否则动画应该停止。

【问题讨论】:

    标签: javascript html amcharts4 webgl-globe


    【解决方案1】:

    动画类有两种方法可以在这里使用:pause()resume()

    文档中的更多信息: https://www.amcharts.com/docs/v4/reference/animation/

    /**
     * ---------------------------------------
     * This demo was created using amCharts 4.
     * 
     * For more information visit:
     * https://www.amcharts.com/
     * 
     * Documentation is available at:
     * https://www.amcharts.com/docs/v4/
     * ---------------------------------------
     */
    
    // Themes begin
    
    am4core.useTheme(am4themes_animated);
    // Themes end
    am4core.options.queue = true;
    am4core.options.onlyShowOnViewport = true;
    var chart = am4core.create("chartdiv", am4maps.MapChart);
    
    // Set map definition
    chart.geodata = am4geodata_worldLow;
    
    // Set projection
    chart.projection = new am4maps.projections.Orthographic();
    chart.panBehavior = "none";
    chart.deltaLatitude = -20;
    chart.padding(20,20,20,20);
    
    // Create map polygon series
    var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
    
    // Make map load polygon (like country names) data from GeoJSON
    polygonSeries.useGeodata = true;
    //polygonSeries.include = ["BR", "UA", "MX", "CI"];
    
    // Configure series
    var polygonTemplate = polygonSeries.mapPolygons.template;
    
    polygonTemplate.fill = am4core.color("#d5ebfe");
    polygonTemplate.stroke = am4core.color("#fff");
    polygonTemplate.strokeWidth = 0.0;
    
    
    
    var graticuleSeries = chart.series.push(new am4maps.GraticuleSeries());
    graticuleSeries.mapLines.template.line.stroke = am4core.color("#00000");
    graticuleSeries.mapLines.template.line.strokeOpacity = 0.00;
    graticuleSeries.fitExtent = false;
    
    chart.maxZoomLevel = 1;
    chart.backgroundSeries.mapPolygons.template.polygon.fillOpacity = 0.0;
    chart.backgroundSeries.mapPolygons.template.polygon.fill = am4core.color("#ffffff");
    
    // Create hover state and set alternative fill color
    
    let animation;
    setTimeout(function(){
      animation = chart.animate({property:"deltaLongitude", to:100000}, 20000000);
    }, 3000)
    
    chart.seriesContainer.events.on("down", function(){
    //  animation.stop();
    })
    
    
    
    ////////////////My added intersectionObserver code////////
    
    function start() {
      animation.resume();
    }
    
    // stop render
    function stop() {
     animation.pause();
    }
    
    const statusElem = document.querySelector('.status');
    
    const onScreen = new Set();
    const intersectionObserver = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          onScreen.add(entry.target);
          start();
          console.log('render has been started');
        } else {
          onScreen.delete(entry.target);
          stop();
          console.log('render has been halted');
            }     
      });
      statusElem.textContent = onScreen.size
        ? `on screen: ${[...onScreen].map(e => e.textContent).join(', ')}`
        : 'none';
    });
    
    document.querySelectorAll('#chartdiv').forEach(elem => intersectionObserver.observe(elem));
    .status {
        position: fixed;
        background: rgba(0,0,0,0.8);
        color: white;
        padding: 1em;
        font-size: medium;
        top: 50%;
        left: 0;
        z-index: 998;
      }
      
      #header{
        position:fixed;
        top: 0px;
        right:0px;
        z-index: 998;
        height: 5em;
        width: 100%;
        background-color: white;
        opacity: 80%;
     }
     
      #chartdiv {
        width: 100%;
        height: 20em;
      max-width:100%;
      
      }
      #section0{
        background-image: linear-gradient(128deg,#340191,#000);
      height: 300vh;
    }
    <body>
     
      <script src="https://www.amcharts.com/lib/4/core.js"></script>
      <script src="https://www.amcharts.com/lib/4/maps.js"></script>
      <script src="https://www.amcharts.com/lib/4/geodata/worldLow.js"></script>
      <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
      
      <div class="status"></div>
    
      <header id="header">
        
        
        
      </header>
    
      <div class="status">status</div>
    
      
     
       
        <div class="section" id="section0">
          <div class="intro">
            
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <div id="chartdiv"></div>
            <script src="js/globe.js"></script>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            <br>
            
          </div>
          
        </div>
    
       
        
    </body>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-25
      • 2015-10-03
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 2012-11-28
      相关资源
      最近更新 更多