You don't need dpi of anything of this sort.
Because you have a box (t-shirt in this case) of fixed and known size and position.
When a user moves an element inside the box you can calculate the element's position and size relative to the box.
And all you need to do is something like:
scale = box.width_in_inches / box.width_in_pixels
el.x_in_inches = (el.x_in_pixels - box.x_in_pixels)*scale
el.y_in_inches = (el.y_in_pixels - box.y_in_pixels)*scale
el.width_in_inches = (el.width_in_pixels )*scale
el.height_in_inches = (el.height_in_pixels )*scale
box.width_in_inches
can change when user selects t-shirt of a different size.
box.width_in_pixels
will change when user zooms the page.
But all *_in_pixels
values will change respectively.
Update:
Answering to your comments:
Maybe your're getting wrong measurements in your code because they are wrong from the beginning: the ratio of t-shirt's width and height
- in inches: 22 / 30.5 = 0.72...
- in pixels of the picture: 452 / 548 = 0,8248... (or on the page in my browser: 1428,750 / 1732,190 = 0,8248...)
in pixels with bounds you've set up: (1428,750−160) / (1732,190−100) = 0,777...
So I had to fix it somehow. I choose to remove the bounds, so that the
logo can move and stretch inside the t-shirt picture freely. And
decided that t-shirt width in inches should be 30.5*(452/548) =
25,157..., not 22.
- Then just as a sound check I set logo width to maximum and move it to the top. Now it's time for experiments. The expected results should be reasonably close to
{ x:0, y:0, w: 25,157, h: 9.07 }
With this function:
// const shirt_w_in_inches = 30.5*(452/548)
const shirt_h_in_inches = 30.5
function get_measurements() {
const pixels_shirt = shirt.getBoundingClientRect()
const pixels_logo = logo .getBoundingClientRect()
const scale = shirt_h_in_inches / pixels_shirt.height
const inches = {
x: (pixels_logo.x - pixels_shirt.x)*scale,
y: (pixels_logo.y - pixels_shirt.y)*scale,
w: (pixels_logo.width )*scale,
h: (pixels_logo.height )*scale,
}
console.log("pixels_shirt", pixels_shirt)
console.log("pixels_logo" , pixels_logo)
console.log("inches" , inches)
return inches
}
I find them quite reasonable.
The worst case I was able to find with an maximum error of around 1% of t-shirt width is when I set a 500% zoom, and refresh the page, and then if I resize my browser to 25% of initial window size (and I couldn't set it less). In this case I get these measurements:
{x: 0.153..., y: 0.172..., w: 24.920..., h: 8.948...}
But if I add inches.width
and inches.x
I will get 25.073 - which gives 0.3% - an average error I've observed.
So you can ask: "What about x
and y
? They are never 0!".
I'm sorry to break it to you but it looks like an issue with Moveable you're using. If I use this function:
function set_full_size() {
const pixels_shirt = shirt.getBoundingClientRect()
const pixels_logo = shirt.getBoundingClientRect()
logo.style.left = shirt.clientLeft + 'px'
logo.style.top = shirt.clientTop + 'px'
logo.style.width = shirt.clientWidth + 'px'
logo.style.height = shirt.clientHeight*pixels_logo.height/pixels_logo.clientWidth + 'px'
}
It not only sets zeros for x
and y
, but also you'll get a smaller error for width. Probably that's because of controls the Moveable puts around logo.