SetInterval配合canvas.js在PHP循环内使用无法持续触发闪烁问题求助
问题根因
你当前生成的setInterval回调逻辑仅会给标记点设置固定的颜色值,每次定时器触发都会重复写入同一个颜色,自然不会产生闪烁效果。你看到的页面加载时的一次变化,只是初始化赋值的视觉效果,后续重复设置相同值不会有视觉变化。
解决方案
修改实现逻辑,先通过PHP预处理出需要闪烁的标记点索引,再统一用单个定时器完成所有点的状态切换,相比原方案每个点单独开定时器的写法性能更高,也能实现预期的闪烁效果。
第一步:修改PHP生成逻辑
<?php $no1 = 0; $blinkPointIndex = []; foreach ($location_data as $last_data) { if ($location[0]->depth_unit == "meter") { $depth_drilled = ($last_data->end_depth - $last_data->start_depth) * 3.28; $acceptable_loss = ((12.25*12.25)/1029.4 * $depth_drilled) / 6.28; } else { $depth_drilled = $last_data->end_depth - $last_data->start_depth; $acceptable_loss = (12.25*12.25)/1029.4 * $depth_drilled; } // 不符合闪烁条件的点直接设为透明 if ($last_data->shaker_loss_value < $acceptable_loss) { echo "chart.options.data[3].dataPoints[{$no1}].markerColor = 'transparent';\n"; } else { // 符合条件的点先设置基础样式,记录到闪烁索引数组 echo "chart.options.data[3].dataPoints[{$no1}].markerType = 'triangle';\n"; echo "chart.options.data[3].dataPoints[{$no1}].markerColor = 'red';\n"; $blinkPointIndex[] = $no1; } $no1++; } // 输出JS可用的闪烁点索引数组 echo "const needBlinkPoints = " . json_encode($blinkPointIndex) . ";\n"; ?>
第二步:添加统一闪烁逻辑
在上述PHP输出的代码之后添加这段JS即可:
// 记录当前闪烁状态,true为显示红色,false为隐藏 let markerVisible = true; // 闪烁间隔单位为毫秒,可根据需求调整速度 setInterval(() => { markerVisible = !markerVisible; // 批量切换所有需要闪烁的点的颜色 needBlinkPoints.forEach(idx => { chart.options.data[3].dataPoints[idx].markerColor = markerVisible ? 'red' : 'transparent'; }); // 统一渲染一次图表即可,无需多次调用 chart.render(); }, 500);
优化说明
- 原方案10个标记点就会创建10个定时器,优化后仅保留1个全局定时器,大幅降低JS线程开销
- 原方案每个定时器内都会调用一次
chart.render(),频繁渲染会导致页面卡顿,优化后单次定时器仅调用一次渲染方法 - 所有业务判断逻辑收拢在PHP侧完成,JS侧仅负责动画执行,逻辑更清晰易于维护
内容的提问来源于stack exchange,提问作者AbcMvc
相关产品推荐
相关产品推荐

