0

I am having trouble drawing an image with CSS filters onto a canvas. I want to apply the CSS filters with sliders/range inputs that I have. The image that the filters will be applied to is an image that you upload from your files. This image is put into a variable in a function I have that will upload the image. The function for the slider is separate, and therefore I can't apply the filters and draw the image again in the function that is activated when the sliders are being dragged.

I need it to be drawn instead of just putting the filters on the canvas itself so that I can download the image with filters.

Here is the javascript code:

var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');

function handleImage(e) {
  var reader = new FileReader();
  reader.onload = function(event) {
    var img = new Image();
    img.onload = function() {
      var ratio = this.height / this.width;
      canvas.height = canvas.width * ratio;
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    }
    img.src = event.target.result;
  }
  reader.readAsDataURL(e.target.files[0]);
}

var container = document.getElementById("container")

var download = document.getElementById("download")
var adjustments = document.getElementById("adjustments")

download.addEventListener("click", function() {
  var link = document.createElement('a');
  link.download = 'filename.png';
  link.href = canvas.toDataURL();
  link.click();
});

var prop1 = document.getElementById("prop1");
var open = true;

adjustments.addEventListener("click", function() {
  if (open === true) {
    prop1.style = "margin-left: -240px;";
    adjustments.classList.remove("line");
    open = false;
  } else if (open === false) {
    prop1.style = "margin-left: 50px;";
    adjustments.classList.add("line");
    open = true;
  }
});

var contrast = document.getElementById("contrast");
var brightness = document.getElementById("brightness");

var slider1 = contrast.value;
var slider2 = brightness.value;

function effect() {
  slider1 = contrast.value;
  slider2 = brightness.value;
  ctx.filter = "contrast(" + slider1 + ") brightness(" + slider2 + ")";
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}

contrast.oninput = function() {
  effect()
};

brightness.oninput = function() {
  effect()
};
Emil
  • 107
  • 2
  • 12
  • Your `img` variable is *scoped* in the `reader.onload` callback function. This means that you can't access it outside of this function's scope. To fix that, declare `var img` in the outer scope (where you declared `var imageLoader` et al.) and in the reader callback remove the `var` keyword, so it assigns that global `img` variable. – Kaiido Mar 09 '21 at 01:14

1 Answers1

0

You could try clearing the canvas with ctx.clearRect() then redraw everything on the canvas. I'd also recommend creating a function to redraw the items just for easier reading.

  • But the image I want to put the filter on is stored on a variable inside of a function. Therefore, I can't use the variable for the image outside of the function. If I had a workaround where I could somehow have the image inside of a variable that could be used anywhere, it would make things significantly easier. – Emil Feb 24 '21 at 21:16
  • Why can't you just put in on the global scale? –  Feb 24 '21 at 21:49
  • Please reply with the code that would fix it. I don't understand what you mean. – Emil Feb 24 '21 at 23:12
  • That's the problem. I can't declare it outside of the function, or at least I don't know how to go about it. The reason I can't is because the image has to be declared inside of the function, since it get uploaded from the user's files. – Emil Feb 25 '21 at 11:39
  • Ok I might need the html and css, so I can see what you have so far, and find a solution to your problem. –  Feb 25 '21 at 14:14