2

Problem definition

I have to render a image as if it were cropped inside a container. The only data I have is the img URL and its bounds in percentages values, expressed as numeric values (left: 86, top: 72, right: 99, bottom: 12, etc...). As you could imagine, the image is bigger than its container.

Code Snippet

Javascript

get pictureProperties() {
    const pic = this.discovery.img;
    const x = this.discovery.crop_percentages.left + '%';
    const y = (100 - this.discovery.crop_percentages.top) + '%';
    return `background-image: url(${pic}); background-position: ${x} ${y}`;
}

Pug

.photo-wrapper(style="{{::$ctrl.pictureProperties}}"

Issues

I tried to position the image as a background inside the container without any luck, because percentage values work as follows with background-images: https://blogsimages.adobe.com/dreamweaver/files/2015/03/percentage-values-illustration-700x345.png While I need something like the absolute values positioning but using this percentages values. enter image description here

Any idea of how can I work around this issue?

Roy Tinker
  • 10,044
  • 4
  • 41
  • 58
Gonzalo Diaz Ailan
  • 583
  • 1
  • 5
  • 23
  • 2
    So, you are saying you just need to convert a percentage to an absolute unit? – Scott Marcus Dec 06 '17 at 20:56
  • 2
    Can you please [edit] your post and include a snippet that demonstrate the issue? You can click on the `<>` button to create one and it will help us understand the issue – Alon Eitan Dec 06 '17 at 20:56
  • @ScottMarcus that could be a solution, of course. I was thinking more about changing `background-position` behavior, but I guess I can do it that way also. The fact is that I don't have the **img** dimensions before it is loaded neither I know how it is gonna to scale when affected by `background-size: cover` – Gonzalo Diaz Ailan Dec 06 '17 at 21:08
  • 2
    _"I was thinking more about changing background-position behavior"_ - that's not possible, that behavior is specified as is ... – CBroe Dec 06 '17 at 21:09
  • @CBroe is there any calculus I can make to "_undo_" this offset or do you think it is better to try with another technique instead of **background-image** ? – Gonzalo Diaz Ailan Dec 06 '17 at 21:14
  • @AlonEitan the edition was made. Thanks for the advice. – Gonzalo Diaz Ailan Dec 06 '17 at 21:15
  • You could have a hidden container that you load the image into with the percentages and use `getComputedStyle()` to then get the converted absolute value that the percentages wound up being. Then, use those values to place the image into the non-hidden container. – Scott Marcus Dec 06 '17 at 21:17
  • Please create an actual [mcve], including an image, so that we can discuss/check the result via a specific example. Also, does the part of the image that is "cut" by those percentages match the aspect ratio of the target element at least? If not, what's supposed to happen in that case? Image to be "squashed" out of proportion to match element dimensions? More parts of the image outside the percentage cut to be shown, if so where, equally distributed on all sides? ...? – CBroe Dec 06 '17 at 21:17
  • Is the image in question part of an image sprite (a sub-area of the whole image at the given URL)? In other words, percentages of _what_? Of the area where the image will go, or of a desired sub-area of the image at the given URL? – Roy Tinker Dec 06 '17 at 22:18
  • @RoyTinker is not a image sprite, but a sub-area of the whole image should be displayed as you describe. The percentages are relative to the image dimensions. What we are trying to show is the result of cropping an image. – Gonzalo Diaz Ailan Dec 07 '17 at 15:00
  • 1
    check the last section of the duplicate answer to find two workarounds – Temani Afif Jan 10 '20 at 00:10

1 Answers1

0

Instead of setting the background-image of the element itself, you could set it to one of the :before/:after pseudo elements and set it to be positioned absolutely. The top/left/right/bottom properties set the top left position of the absolutely positioned element. Live example here: https://jsfiddle.net/1oyewhuo/

#xyz{
  position: relative;
  height: 200px;
  width: 400px;
  background-color: red;
}

#xyz:after{
  background-image: url("http://lorempixel.com/400/200/sports/2/");
  background-repeat: no-repeat;
  background-size: cover;
  position: absolute;
  content: '';
  top: 50% /* this.discovery.crop_percentages.top */;
  left: 25% /* this.discovery.crop_percentages.left */;
  right: 25% /* this.discovery.crop_percentages.right */;
  bottom: 25% /* this.discovery.crop_percentages.bottom */;
}
<div id="xyz"></div>
Pat
  • 2,540
  • 1
  • 21
  • 28