Processing如何实现多张图片错峰启动无限循环淡入淡出效果
Processing逐图错峰淡入淡出动画实现方案
原有代码问题
所有Pic实例的动画计数器在实例创建后同步启动计数,没有设置逐图的启动偏移;同时基于帧变量累加的计时逻辑会受实际运行帧率影响,无法稳定保证15秒的动画周期,最终出现所有图片动画同步的问题。
修改思路
- 采用Processing内置
millis()函数作为统一时间基准,该函数返回程序启动后累计经过的毫秒数,不受帧率波动影响,可精准控制动画时长。 - 为每个
Pic实例增加独立的启动延迟属性:按图片排列顺序,第i张图片的启动延迟为i * 1000毫秒,实现逐张延迟1秒启动的效果。 - 设定单张图片动画总周期为15000毫秒(即15秒),对每个实例计算「当前运行时间 - 自身启动延迟」,再对总周期取模,即可得到无限循环状态下该实例在单个动画周期内的本地进度,无需额外维护计数方向标记变量。
- 按本地进度计算透明度:前7.5秒(半周期)透明度从0线性增长到255完成淡入,后7.5秒透明度从255线性降低到0完成淡出。
修正后完整代码
PImage[] imgs = new PImage[42]; Pic[] pics = new Pic[15]; // 动画配置常量 final int ANIM_CYCLE = 15000; // 单张图动画总周期15秒(单位:毫秒) final int DELAY_PER_PIC = 1000; // 每张图延迟1秒启动 void setup() { size(1000, 880); imageMode(CENTER); // 全局设置图片绘制模式,无需重复调用 // 初始化图片实例,传入逐图延迟 for (int i = 0; i < pics.length; i++) { pics[i] = new Pic( int(random(0, 29)), random(0, 800), random(0, height), i * DELAY_PER_PIC // 第i张图延迟i秒启动 ); } // 加载素材 for (int i = 0; i < imgs.length; i++) { imgs[i] = loadImage(i+".png"); } } void draw() { background(255); for (int i = 0; i < pics.length; i++) { pics[i].display(); } } class Pic { float x; float y; int num; int startDelay; // 实例专属启动延迟 Pic(int tempNum, float tempX, float tempY, int tempDelay) { num = tempNum; x = tempX; y = tempY; startDelay = tempDelay; } void display() { // 计算当前实例在动画周期内的本地时间 long localTime = (millis() - startDelay) % ANIM_CYCLE; int alpha = 0; int halfCycle = ANIM_CYCLE / 2; if (localTime >= 0) { if (localTime < halfCycle) { // 前半周期:淡入,透明度0->255 alpha = (int)map(localTime, 0, halfCycle, 0, 255); } else { // 后半周期:淡出,透明度255->0 alpha = (int)map(localTime, halfCycle, ANIM_CYCLE, 255, 0); } } // 未到启动时间时localTime为负,透明度保持0即可 tint(0, 153, 204, alpha); image(imgs[num], x, y); } }
效果说明
代码运行后会自动按顺序逐张启动淡入淡出动画,单张图完整走完淡入+淡出流程刚好15秒,所有图片动画错开1秒相位,程序会无限循环运行该效果,不会出现同步问题。
内容的提问来源于stack exchange,提问作者user2449986
相关产品推荐
相关产品推荐

