2

Quick and simple: Is there a way that I can achieve the following effect after clicking on an active FabricJS element or active selection? Basically, as well as the border, I'd like to render a shadow/border effect around the active elements. Once you click away, the shadow will be removed.

Example code: (sourced from this answer)

img {
  -webkit-filter: drop-shadow(1px 1px 0 black)
                  drop-shadow(-1px -1px 0 black);
  filter: drop-shadow(1px 1px 0 black) 
          drop-shadow(-1px -1px 0 black);
}

body {
  background-color: lightcoral;
}
<img src="http://i.imgur.com/GZoXRjS.png" width="250">
Venk
  • 230
  • 2
  • 19
  • Do you need the full flexibility of shadows from CSS, or could you get by using the `fabric.Shadow` class (http://fabricjs.com/docs/fabric.Shadow.html)? If you just need simple shadows, you could add an event listener for selection/deselection to add/remove the shadow from the selected object. – Ben Jan 04 '21 at 23:07

4 Answers4

3

Basically you need to use fabricjs events and set or unset the shadow on the image object.

var canvas = new fabric.Canvas("c");
fabric.Image.fromURL('https://i.imgur.com/GZoXRjS.png', function(img) {
img.scaleToWidth(500)

canvas.add(img)

img.on('deselected',function(e){
    this.set('shadow', null);
})
});


canvas.on('object:selected',function(e){
debugger;
  if(e && e.target){
    e.target.set('shadow', { blur: 15, offsetX: 0, offsetY: 0});
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.15/fabric.min.js"></script>
<canvas width=800 height=800 id="c" ></canvas>
Marius Turcu
  • 1,511
  • 7
  • 14
0

Solution

Using eventListener on the body element.

  • When the Image was clicked checking by the tagName then the css styles will be applied.
  • When the body was clicked then the applied styling will be reset using the attribute value none

In the snippet you can see the behavior

let pic = document.getElementById("demo-pic");

document.body.addEventListener("click", function (e) {
  if (e.target.tagName === "IMG") {
    pic.setAttribute(
      "style",
      "-webkit-filter: drop-shadow(1px 1px 0 black)drop-shadow(-1px -1px 0 black);filter: drop-shadow(1px 1px 0 black) drop-shadow(-1px -1px 0 black);"
    );
    document.body.style.backgroundColor = "lightcoral";
  } else if (e.target.tagName === "BODY") {
    pic.setAttribute("style", "-webkit-filter: none;");
    document.body.style.backgroundColor = "white";
  }
});
<!DOCTYPE html>
<html>
<head>
    <script src="fabric.js"></script>
    <link rel="stylesheet" href="mydemo.css">
</head>

<body>
    <canvas id="c"></canvas>
    <img id="demo-pic" src="http://i.imgur.com/GZoXRjS.png" width="250">
    <script src="mydemoFile.js"></script>

</body>
</html>
Aalexander
  • 4,987
  • 3
  • 11
  • 34
0

Possibly using the focus pseudo element like this in conjunction with an a tag could achieve what you are looking for.

Take a look here:

a:focus img{
  -webkit-filter: drop-shadow(1px 1px 0 black)
                  drop-shadow(-1px -1px 0 black);
  filter: drop-shadow(1px 1px 0 black) 
          drop-shadow(-1px -1px 0 black);
}

body {
  background-color: lightcoral;
}
<a href="#"><img src="http://i.imgur.com/GZoXRjS.png" width="250">
John
  • 5,132
  • 1
  • 6
  • 17
0

Thanks to this answer.

if you give your img tag a tabindex then you can use the focus psuedo class to simulate a click.

however i had to remove the outline:

img:focus {
  outline:0;
  -webkit-filter: drop-shadow(1px 1px 0 black)
                  drop-shadow(-1px -1px 0 black);
  filter: drop-shadow(1px 1px 0 black) 
          drop-shadow(-1px -1px 0 black);
}
body {
  background-color: lightcoral;
}
<img src="http://i.imgur.com/GZoXRjS.png" width="250" tabindex="0">
Alan Omar
  • 4,023
  • 1
  • 9
  • 20