Home > Back-end >  Why updating brightness filter has not effect in Safari?
Why updating brightness filter has not effect in Safari?

Time:12-31

I'm updating DOM element's brightness/contrast from JavaScript:

let style = `brightness(${brightness}%) contrast(${contrast}%)`;
element.style.filter = style;

This happens when the user holds left mouse button and moves cursor. However, the brightness/contrast does NOT change in Safari (on Mac) unless the scroll bars are visible. However, the brightness does change in other browsers (Chrome, Firefox, Edge). Is it a bug in Safari? How do I make it work in Safari?

Demo: https://l36vng.csb.app/

Code: https://codesandbox.io/s/charming-vaughan-l36vng?file=/main.js:2207-2306

PS. This also does not work in Safari on iOS (if I include touch event handlers to the code above). My Mac Safari version is 16.1.

CodePudding user response:

This seems to be fixed in the latest Technology Preview (Release 160 (Safari 16.4, WebKit 18615.1.14.3)).

For the time being, you can workaround the issue by adding a super fast transition on the filter property, this will make current stable happy and update the filter as expected.

// Change brightness/contrast of the image by holding
// left mouse button on the image and moving cursor.
// Moving horizontally changes brightness,
// moving vertically changes contrast.
class Brightness {
  constructor(element) {
    this.element = element;

    // x and y mouse coordinates of the cursor
    // when the brightness change was started
    this.startPosition = null;

    this.brightnessPercent = 100;

    // Current brightness/contrast percentage.
    this.currentAmount = {
      brightness: 100,
      contrast: 100
    };

    // True if the user holds left mouse bottom, which
    // indicates that brightness is being changed.
    // False by default or when the left mouse button is released.
    this.active = false;

    this.addEventListeners();
  }

  addEventListeners() {
    let element = this.element;

    // Start changing brightness
    // -----------------

    element.addEventListener("mousedown", (e) => {
      if (e.button !== 0) return; // Not a left mouse button
      this.active = true;
      e.preventDefault();
      this.startChange(e);
    });

    // End changing brightness
    // -----------------

    document.addEventListener("mouseup", () => {
      this.active = false;
    });

    // Drag the pointer over the bar
    // -----------------

    document.addEventListener("mousemove", (e) => {
      if (!this.active) return;
      this.change(e);
    });
  }

  startChange(e) {
    this.startPosition = this.positionFromCursor(e);
  }

  change(e) {
    let position = this.positionFromCursor(e);

    let xChange = position.x - this.startPosition.x;
    this.changeCurrentAmount(xChange, "brightness");

    let yChange = position.y - this.startPosition.y;
    this.changeCurrentAmount(yChange, "contrast");

    this.changeImageStyle();
  }

  changeCurrentAmount(change, type) {
    change /= 2; // Decrease rate of change
    change = Math.round(change);
    let amount = 100   change;
    if (type === "contrast") amount = 100 - change;
    if (amount < 0) amount = 0;
    this.currentAmount[type] = amount;
  }

  changeImageStyle() {
    let brightness = this.currentAmount.brightness;
    let contrast = this.currentAmount.contrast;
    let css = `brightness(${brightness}%) contrast(${contrast}%)`;
    this.element.style.filter = css;
  }

  positionFromCursor(e) {
    let pointerX = e.pageX;
    let pointerY = e.pageY;

    if (e.touches && e.touches.length > 0) {
      pointerX = e.touches[0].pageX;
      pointerY = e.touches[0].pageY;
    }

    return { x: pointerX, y: pointerY };
  }
}

document.addEventListener("DOMContentLoaded", function () {
  const imageElement = document.querySelector(".Image");
  new Brightness(imageElement);
});
.Image {
  /* Safari bug workaround */
  transition: filter 1e-6s linear;
}
<img
    
    width="512"
    height="512"
    src="https://64.media.tumblr.com/df185589006321d70d37d1a59040d7c3/df57f19b4b4b783a-cb/s250x400/e76347d6b1cb4aa08839036fb0407a9f6108a0ab.jpg"
  />

  • Related