If you can fade an image, then you can also cross fade an image by subtracting the fade amount from the maximum fade value (e.g. inverting the fade value).
In your case you're using tint so it's a value from 0-255.
Let's say tint
is your variable: 255 - tint
would be the inverted value.
Here's a basic sketch you can run that illustrates this (using fill()
instead of tint()
):
void draw(){
float fade = map(sin(frameCount * 0.03), -1.0, 1.0, 0, 255);
background(0);
noStroke();
// use fade value
fill(192, 0, 192, fade);
ellipse(45, 50, 60, 60);
// invert the fade value (by subtracting it from the max value)
fill(0, 192, 192, 255 - fade);
ellipse(60, 50, 60, 60);
}
Continuing from the previous question and answer you can tweak the code to use an inverted tint value to crossfade. The catch is you'd need to store a reference to the previous image to apply the inverted tint to:
PImage[] imgs = new PImage[42];
ImagesFader fader;
void setup(){
size(255, 255);
frameRate(60);
// load images
for (int i = 0; i < imgs.length; i++) {
imgs[i] = loadImage(i+".png");
}
// setup fader instance
// constructor args: PImage[] images, float transitionDurationSeconds, int frameRate
// use imgs as the images array, transition in and out within 1s per image at 60 frames per second
fader = new ImagesFader(imgs, 3.0, 60);
}
void draw(){
background(0);
fader.draw();
}
class ImagesFader{
int numFrames;
int numFramesHalf;
int frameIndex = 0;
PImage[] images;
int maxImages = 15;
int randomImageIndex;
float randomX, randomY;
PImage previousImage;
float previousX, previousY;
ImagesFader(PImage[] images, float transitionDurationSeconds, int frameRate){
numFrames = (int)(frameRate * transitionDurationSeconds);
numFramesHalf = numFrames / 2;
println(numFrames);
this.images = images;
// safety check: ensure maxImage index isn't larger than the total number of images
maxImages = min(maxImages, images.length - 1);
// pick random index
randomizeImage();
}
void draw(){
updateFrameAndImageIndices();
PImage randomImage = imgs[randomImageIndex];
// isolate drawing style (so only the image fades, not everything in the sketch)
pushStyle();
// if there is a previous image, cross fade it
float tintAlpha = tintFromFrameIndex();
if(previousImage != null){
// invert tint -> max(255) - value
tint(255, 255 - tintAlpha);
image(previousImage, previousX, previousY);
}
// render current random image (on top of the previous one, if any)
tint(255, tintAlpha);
image(randomImage, randomX, randomY);
popStyle();
}
float tintFromFrameIndex(){
int frameIndexToTint = abs(frameIndex - numFramesHalf);
return map(frameIndexToTint, 0, numFramesHalf, 255, 0);
}
void updateFrameAndImageIndices(){
// increment frame
frameIndex++;
// reset frame (if larger than transition frames total)
if(frameIndex >= numFrames){
// update previous image before generating another random image
previousImage = imgs[randomImageIndex];
previousY = randomX;
previousY = randomY;
frameIndex = 0;
// randomize index and position
randomizeImage();
println("fade transition complete, next image: ", randomImageIndex);
}
}
void randomizeImage(){
randomImageIndex = int(random(0, 29));
randomX = random(width);
randomY = random(height);
}
}
The above skeetch might not be 100% accurate (as I don't fully get the randomisation logic), but hopefully it illustrates the mechanism of crossfading.