Open RawToast opened 5 years ago
After reflection I think this can be fixed rather nicely.
In other places you use a getLeft
function, like so:
let rect = getBoundingClientRect(canvas);
let x = getClientX(e) - getLeft(rect);
The rect also holds the actual width/height by adding methods like so:
[@bs.get] external getRectWidth : 'a => int = "width";
[@bs.get] external getRectHeight : 'a => int = "height";
Then the canvas details in style need to be fetched. One way is to grab them from the style
in the canvas element, like so:
let style = getStyle(canvas);
let canvasWidth = canvas |> getStyle |> getWidthStyle |> s => Js.String.slice(0, Js.String.length(s) - 2, s) |> int_of_string;
Although, the style in canvas is passed in -- so I might be able to just store and access that value rather than read the dom.
This would let you compare the actual width with the one in Reprocessing and simply use a simple calculation: x => x (canvasWidth / rectWidth)
I'll try this out tonight and raise a PR if it's successful.
A simple solution, just for mouseDown: https://github.com/RawToast/reasongl/blob/96ab27a508f31baa89b79578a7267d6b2dadaa83/src/web/reasongl_web.re#L340-L354
let rect = getBoundingClientRect(canvas);
let left = getLeft(rect);
let top = getTop(rect);
let actualWidth = getRectWidth(rect);
let actualHeight = getRectHeight(rect);
let style = getStyle(canvas);
let removePx = s => Js.String.slice(0, Js.String.length(s) - 2, s) |> float_of_string;
let width = style |> getWidthStyle |> removePx;
let height = style |> getHeightStyle |> removePx;
let state = Events.MouseDown;
let x = int_of_float((float_of_int(getClientX(e) - left)) *. (width /. actualWidth));
let y = int_of_float((float_of_int(getClientY(e) - top)) *. (width /. actualWidth));
cb(~button, ~state, ~x, ~y);
Makes sense in general, we could add some helper function that does this kind of division and use it for all the mouse events, would be great to be able to fix this.
On the other hand, can we rely on the style.width and style.height? Could they be specified in values other than px? Or set indirectly using max-width
or something?
I think it is Reprocessing that sets those styles -- so it is rathe Reprocessing specific! I'd rather take it from the size given
Maybe add two Ref
fields on initialisation and updating them on calls like windowResize
would be a more generic implementation -- and more performant. In the unlikely event the Ref is None
we could just not do the calculation.
Oh I see, I was looking at it backwards. You're basically pulling the values from here, right: https://github.com/bsansouci/reasongl/blob/868ca060c7fe41595fe6157c7ab668af82a170e1/src/web/reasongl_web.re#L234-L245
Seems like it could be ok in that case? Not sure what kind of css you're imagining to increase the canvas size.
Yeah, that's where I get it. -- but I think a ref would be the better solution.
I already am manipulating the canvas, check it out The canvas is 568px by 320px, but via the all powerful !important
I can stretch it 😆
<style>
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
#gameContainer canvas {
display:block;
width: 100% !important;
height: 100% !important;
}
div#webgl-content {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
</style>
</head>
<body style="display:flex;flex-wrap:wrap; background-color: #222; ">
<div id="webgl-content" style="width:80%; height: 80%; min-height: 320px; max-height: 480px; min-width:568px; max-width:852px;">
<div id="gameContainer" style="width: 100%; height: 100%">
<canvas id="game" width="1136" height="640" style="background-color: black; width: 568px; height: 320px;"></canvas>
<script src="main.js"></script>
</div>
</div>
The co-ordinates given for x/y mouse positions are not based on the actual canvas size. If the canvas size is increased (via CSS) then the values are based on the actual pixels and not canvas units.
Updating the mouse and touches sections as follows seems to resolve this; although, pixelWidthX/Y might be better candidates for this change.
Edit: that's no good. It just happened to be closer as my canvas was ~x1.8 and my machines ratio is x2.