ThreeJS : fit camera zoom according to a DOM element - javascript

I just begin to learn Three js and I face to a problem when tryng to add a plane geometry based on a img tag on the dom.
Context
Here is my actuel html template :
<figure>
<div class="aspect" />
<img class="img" src="#/assets/images/project1.jpg" />
</figure>
The img tag is hidden by css property display: none and the .aspect div give the size of the element by receiving width: 50vw and padding-top: 60%
I calculate the width - height of the element by using getBoundingClientRect func and applying it to the plane geometry like that :
const geometry = new THREE.PlaneBufferGeometry(el.width, el.height, 5)
Then I simply apply the texture of my image to it
My problem
As you can see on the screenshots, the plane geometry has not the exact size of my aspect div (in red) :
For the moment I manually set the z axis of my camera, but I know it's not the good solution and just wanted to know if there was an existing solution to acheive this ?
Thank you in advance !

Solved by using an OrthographicCamera
Doc here :
https://threejs.org/docs/#api/en/cameras/OrthographicCamera

Related

Dynamically resize canvas on window resize

I am attempting to resize a canvas chart when a user resizes their browser window. The problem with changing it directly, or so I've found...is that the image disappears during the resizing. Here are some screenshots to help you understand my problem.
This is the chart before resizing.
This is the chart during the resizing. (without targeting the DOM element)
I've identified the chart overflowing on the right hand side.
Chart being resized and targeting the canvas width.
As you can see, the chart disappears.
let canvas = document.getElementById('canvas');
this.canvas.width = ${
event.target.innerWidth - (window.innerWidth / 100) * 2
};
Please let me know what options I have for dynamically resizing canvas charts. Thanks!
P.S. I'm using AngularJs for this particular project.
Update 12/30/2020
Discovered that the obvious reason for the chart disappearing is that the canvas is based on coordinates which originate from a set height/width. So the solution was re-mapping the strokes/fills as the canvas is resizing.
New challenge:
Using clearRect (0, 0, width, height) doesn't clear the canvas. Re-mapping results in an inifite mapping of charts on top of one another. As shown in the photo below.
Is this the solution I get paid a million dollars for? No. But...
After hours of spinning around thoughts as to why the creators never made an easy solution for resizing a canvas, I've finally found an option that works for resizing the charts. Note that if you're scaling up that it can become pixelated. But this option will work.
Instead of defining the height and width with the inline properties:
<canvas id="canvas" height="200" width="600" (window:resize)="onResize($event)"> </canvas>
You should use css to make the height and width 100%. This turns the canvas into an image essentially. Which is why it pixelates when you scale up. The next step is to setup functionality or styling for the element that the canvas is embedded within. This is where the solution arises. Because you can't adjust the canvas without losing the graphic. You have to adjust the element that encapsulates it!
Ex:
<div id="area-chart">
<canvas id="canvas" (window:resize)="onResize($event)"> </canvas>
</div>
You would dynamically adjust the height and width of the #area-chart. I personally suggest using viewport width to define the height as it is the most flexible in terms of scaling and the graphic pixelates far less than using other measurements (%, px, pt, etc.). Of course your needs may be different than mine, but here's some sample styling.
Sample scss:
#area-chart {
#canvas {
width: 100%;
height: 10vw;
}
}
Chart on load:
Chart scaled down:
Chart scaled up:
** note that the pixel dimensions in the screenshots are the full window size and not the size of the element

How to get the actual width of a rotated canvas rectangle

I'm using konva js to make a transformable rectangle. I'm able to access the width of the rectangle using
rect1.getClientRect().height
. However, when I rotate the rectangle, the width property is changing. I believe width property gives the overall horizontal length of the container of the rectangle canvas. Is there any way I can get the actual width of the rotated rectangle. Here's the jsfiddle
The Konva-object has an attrs attribute: rect1.attrs.width * rect1.attrs.scaleX
https://jsfiddle.net/8gack34s/4/
there is also attrs.rotation that you can use to calculate it mathematically.
Konva warning: Konva.Transformer is currently experimental and may have bugs. Please report any issues to GitHub repo.

Split an img element into four equal sized smaller img elements using Javascript

I am trying to figure out how to take a given img element and, using Javascript, split that img into four equal sized tiles. That is, the upper-left quadrant of the original image would become its own img element, as the same with the other three quadrants. However, I am at a loss as to how I could do this. Could somebody offer a starting point or explain how/if this could be done? Would it have to be brute pixel manipulation?
I believe the best solution here would be to use a canvas. The only caveat being that the original image must either be served locally or served via CORS. The steps to complete this solution would be to:
Select the image, or set the source of the image via javascript (if it is not displayed)
Onload of the image, create 4 canvases each 1/4 the size of the image
Using drawImage, draw each quarter of the image to each small canvas
Get each image source of each canvas (canvas.toDataUrl)
Create new image elements and set their source to each of new sources
The entire solution can be viewed on the linked codepen example.
codepen example
You could do something like this in jQuery:
<div id="img">
<img src="myimage.png" alt="" style="width: 100px; height: 100px;" />
</div>
<script>
var imgSrc = $("#img img").attr("src");
for(var i=0; i<4; i++)
$("#img").append($("<div></div>").attr("src", imgSrc).css({ width: (imgWidth / 4), height: (imgHeight / 4) }));
</script>

Coordinates of a scaled canvas element

I already made use of a search engine, but I did not get the information I wanted, so I want to ask whether someone has a good method/trick for using a self-made coordinate system in a HTML5 canvas element.
I want to develop a 2D game in HTML5 using the canvas element, which should adapt to the whole browser window, like so:
<canvas style="width: 100%; height: 100%;">
No support for your browser, unfortunately...
</canvas>
The problem is that I do not know how I should manage the coordinates of my game.
In my game the player e.g. moves 32px to the right immediately when the user presses the right arrow key, but what happens, if I resize the canvas element?
Logically the "blocks" of the game will change their size too, so the unit of the coordinates will not be pixels anymore.
Are there other units I could use or what would you suggest me to do?
Set canvas width and height attributes to game area size
<canvas id="mycanvas" width="400" height="300"/>
And set its style to the desired display size on screen.
#mycanvas {
width: 100%
height: 100%
display: block
}
Now you can always assume in the code that canvas is 400x300 and when drawing ignore the actual physical pixel size on screen.
You need to scale the mouse clicks to correspond the actual location on game coordinates. So if you get mouse click on canvas at (x, y) you get location on game coordinates by x = ( x / $('#mycanvas').width()) * 400 and y likewise. If canvas is not full screen, use the $('#mycanvas').offset() to get delta for click coordinates.
Never ever ever use CSS sizing for the canvas, they will make things very ugly.
What you wrote does not make your canvas the width of the page, it makes it 300 pixels wide by 150 pixels tall (the default) and then warps that until its the width and height of the page.
Stick to the width and height attributes that Canvas has instead of using CSS.
If you want to make it the size of the page you have other options, such as putting the canvas inside a div and then making canvas.width equal to the div.style.clientWidth.
For working with different (fullscreen or not) window sizes, see my answer talking about "model coordinates" here: Working with canvas in different screen sizes

Grid drawn using a <canvas> element looking stretched

I'm trying to draw a grid on a <canvas> element with the ultimate goal of making a Go board.
For some reason the grid is looking stretched, with the lines being thicker than 1 pixel and the spacing being completely wrong. It doesn't even start in the (10,10) position..
It would be great if someone could take a look at tell me what I'm doing wrong.
http://jsfiddle.net/h2yJn/
I've found the problem. I was setting the dimensions of the <canvas> using CSS, when you actually have to set the width and height attributes. This was causing it to be stretched/skewed.
var canvas = $('<canvas/>').attr({width: cw, height: ch}).appendTo('body');
http://jsfiddle.net/h2yJn/66/
Please try it outside jsfiddle, maybe jsfiddle is applying some linear transformation.
Also please make sure that you add 0.5 everywhere to both x and y coordinates. Alternatively, you can apply translate(0.5, 0.5) to shift all coordinates by half a pixel.

Categories

Resources