• Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
MagicMirror Forum
  • Recent
  • Tags
  • Unsolved
  • Solved
  • MagicMirror² Repository
  • Documentation
  • 3rd-Party-Modules
  • Donate
  • Discord
  • Register
  • Login
A New Chapter for MagicMirror: The Community Takes the Lead
Read the statement by Michael Teeuw here.

Contrasting text on changing background

Scheduled Pinned Locked Moved General Discussion
4 Posts 4 Posters 991 Views 5 Watching
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    mwm341
    last edited by Jul 27, 2021, 12:36 PM

    I’m trying to come up with a configuration that (mostly) guarantees text visibility in the following way:

    White background shows black text and vice versa
    Yellow background shows blue text and vice versa

    …the point being that the text color should ALWAYS be different from the background color, so that it can be read even if the background color changes. I’d also like that to happen with randomly-selected wallpapers.
    So I’m wondering: Is it something I can do with CSS?
    Or do I need to try something else?

    S 1 Reply Last reply Jul 27, 2021, 12:48 PM Reply Quote 0
    • S Do not disturb
      sdetweil @mwm341
      last edited by sdetweil Jul 27, 2021, 12:59 PM Jul 27, 2021, 12:48 PM

      @mwm341 I want that too. text over photos. haven’t figured out a way yet.

      some kind of css transform i think

      https://css-tricks.com/methods-contrasting-text-backgrounds/
      https://stackoverflow.com/questions/50986688/invert-text-color-based-on-background-in-css

      Sam

      How to add modules

      learning how to use browser developers window for css changes

      M B 2 Replies Last reply Jul 29, 2021, 11:11 AM Reply Quote 1
      • M Offline
        mwm341 @sdetweil
        last edited by Jul 29, 2021, 11:11 AM

        @sdetweil I guess one could cheat a little by doing something with an animated (slow) colour gradient, assuming that the text will be visible some of the time (in the place where I do it) - but that not much of a solution… (sigh)

        1 Reply Last reply Reply Quote 0
        • B Offline
          botts85 @sdetweil
          last edited by botts85 Feb 26, 2025, 4:17 PM Feb 26, 2025, 4:08 PM

          @sdetweil said in Contrasting text on changing background:

          @mwm341 I want that too. text over photos. haven’t figured out a way yet.

          I kludged something together today with the MMM-Wallpaper module. It’s not elegant, but it’s been working for me so far.

          What I’m doing is having the module draw the image onto an off-screen canvas and compute its average brightness using the luminance formula. Based on whether this brightness exceeds a defined threshold (115 has been working for me), the module then updates a global CSS variable with either a light or dark text color.

          I’m using color: var(--dynamic-text-color); as the variable. Since it’s determining global brightness, it can still “miss” picking a good color for each module.

          Depending on compute load, I’m thinking an update would be to determine that brightness value for each quadrant of an image then creating a variable for each quadrant and setting the text style in those areas to that color. A downside to this approach is that it won’t work perfectly with different display aspect ratios, but if you’re only ever using a 16:9 display that would be mitigated.

          Brightness function:

            // Helper function to compute average brightness of an image.
            getAverageBrightness: function(image, callback) {
              var canvas = document.createElement("canvas");
              var width = image.naturalWidth;
              var height = image.naturalHeight;
              canvas.width = width;
              canvas.height = height;
              var context = canvas.getContext("2d");
          
              context.drawImage(image, 0, 0, width, height);
          
              try {
                var imageData = context.getImageData(0, 0, width, height);
              } catch (error) {
                console.error("Error accessing image data:", error);
                callback(255);  // Assume bright background if error.
                return;
              }
              
              var data = imageData.data;
              var colorSum = 0;
              var pixels = data.length / 4;
          
              for (var i = 0; i < data.length; i += 4) {
                var r = data[i];
                var g = data[i + 1];
                var b = data[i + 2];
                // Calculate brightness using the luminance formula.
                var brightness = 0.299 * r + 0.587 * g + 0.114 * b;
                colorSum += brightness;
              }
          
              var averageBrightness = colorSum / pixels;
              callback(averageBrightness);
            },
          

          Updated onImageLoaded function:

            onImageLoaded: function(imageData, element) {
              var self = this;
              return () => {
                self.resetLoadImageTimer();
          
                element.className = `wallpaper ${self.config.crossfade ? "crossfade-image" : ""}`;
                element.style.opacity = 1;
                
                // Analyze the image brightness and adjust text color accordingly.
                // This will update both the module's caption and a global CSS variable.
                self.getAverageBrightness(element, function(brightness) {
                  var threshold = 128; // Adjust this threshold as needed.
                  var textColor = brightness > threshold ? "black" : "white";
                  self.title.style.color = textColor;
                  // Set a global CSS variable for dynamic text color.
                  document.documentElement.style.setProperty('--dynamic-text-color', textColor);
                });
          
                self.title.style.display = "none";
          
                setTimeout(() => {
                  var caption = imageData.caption;
                  if (self.config.caption && caption) {
                    self.title.innerHTML = caption;
                    self.title.style.display = "initial";
                  }
          
                  if (self.imageElement !== null) {
                    self.content.removeChild(self.imageElement);
                  }
                  self.imageElement = self.nextImageElement;
                  self.nextImageElement = null;
                }, self.config.crossfade ? 1000 : 0);
              };
            },
          
          1 Reply Last reply Reply Quote 1
          • 1 / 1
          • First post
            Last post
          Enjoying MagicMirror? Please consider a donation!
          MagicMirror created by Michael Teeuw.
          Forum managed by Sam, technical setup by Karsten.
          This forum is using NodeBB as its core | Contributors
          Contact | Privacy Policy