如何停止和启动AMcharts与intersectionObserver全球动画?



我的网站首页上有这个来自AMcharts的旋转地球仪动画。但它消耗了大量的系统资源,甚至当它从屏幕上滚动时,任何更多的动画按钮添加到网站上都会使chrome慢得像爬行一样。我做了一些研究在过去几天如何停止和启动three.js动画,和帆布动画和观察者发现了十字路口,我复制粘贴一些代码的地方,我发现它和添加,似乎我失踪的实际停止和启动功能从AMcharts intersectionobserver可以钩住来控制动画与我相交时div的id ="status"

我已经研究了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相交时,动画将运行,否则动画将停止。

动画类有两个方法可以在这里使用: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>

最新更新