Is there a way to preserve image proportions when using an <a-image> tag? - aframe

Is there a way to preserve image proportions when using an tag?
The docs mention hard coding the dimensions but that's problematic when requesting arbitrary images
https://aframe.io/docs/0.6.0/primitives/a-image.html

as far as i see, the a-image is just a a-plane with an image source in a material.
It means the image will be streched over the plane, you can only mess with the
<a-image> height and width, which are the a-plane's height and width in meters,
<img> height and width, which specify the image dimensions in px, but the image still will be streched over the plane.
You could try to do it automatically, within a component, setting the a-planewidth and height depending on the input <img> width and height, having a px-meters ratio:
AFRAME.registerComponent('imageSetter',{
schema:{
img:{type:'selector'}
},
init:function(){
let lowResRatio = 0.01;
this.el.setAttribute('height',this.data.img.height*lowResRatio);
this.el.setAttribute('width',this.data.img.width*lowResRatio);
}
});
Check it out in my fiddle: https://jsfiddle.net/gftruj/5d9j9nqm/2/.
Otherwise, You need to prepare the images earlier on.
UPDATE
You can modify the component so it gets the image dimensions, gets a height/width ratio, and sets the width and height accordingly:
AFRAME.registerComponent('foo',{
schema:{
img:{type:'selector',default:''},
height:{}
},
init:function(){
let data = this.data;
let ratio = 1/100;
this.el.setAttribute('width',data.img.width*ratio);
this.el.setAttribute('height',data.height);
this.el.addEventListener('materialtextureloaded', (e)=>{
var w = e.detail.texture.image.videoWidth || e.detail.texture.image.width;
var h = e.detail.texture.image.videoHeight || e.detail.texture.image.height;
let ratio = w/h;
this.el.setAttribute('width',data.height*ratio);
});
}
})
live fiddle here: https://jsfiddle.net/5d9j9nqm/4/
Now it's fixing itself to a given height.

Related

compute mouse position within video with object-fit:contain

I am trying to convert a mouse event to pixel coordinates within a video. By pixel coordinates, I mean coordinates relative to the original video resolution.
My video element has object-fit: contain, which means that the top left corner of the video is not necessarily located at position (0,0), as this picture shows:
If I click on the top-left corner of the white section in this video then I want to get (0,0), but in order to do this I need to discover the offset of the video content (white area) relative to the video element (black border).
How can I recover this offset?
I am already aware of width, height, videoWidth, and videoHeight, but these only let me account for the scaling, not the offset.
The offset can be deduced. I think this kind of code should do the trick:
if(videoHeight/height > videoWidth/width){
scale = videoHeight/height;
offsetX = (videoWidth - width*scale)/2;
offsetY = 0;
}
else{
scale = videoWidth/width;
offsetY = (videoHeight - height*scale)/2;
offsetX = 0;
}
I was also interested in getting the actual pixel positions from mouse or touch events when using object-fit, and this is the only result I found when searching. Although I suspect it is probably too late to be helpful to you, I thought I'd answer in case anybody else comes across this in future like I did.
Because I'm working on code with other people, I needed a robust solution that would work even if someone changed or removed the object-fit or object-property in the css
The approach that I took was:
Implement the cover, contain etc algorithms myself, just functions doing math, not dependent on the DOM
Use getComputedStyle to get the element's objectFit and objectPosition properties
Use .getBoundingClientRect() to get the DOM pixel size of the element
Pass the element's current objectFit, objectPosition, its DOM pixel size and it's natural pixel size to my function to figure out where the fitted rectangle sat within the element
You then have enough information to transform the event point to a pixel location
There's more code than would comfortably fit here, but getting the size of the fitted rectangle for cover or contain is something like:
if ( fitMode === 'cover' || fitMode === 'contain' ) {
const wr = parent.width / child.width
const hr = parent.height / child.height
const ratio = fitMode === 'cover' ? Math.max( wr, hr ) : Math.min( wr, hr )
const width = child.width * ratio
const height = child.height * ratio
const size = { width, height }
return size
}
// handle other object-fit modes here
Hopefully this gives others a rough idea of how to solve this problem themselves, alternately I have published the code at the link below, it supports all object-fit modes and it includes examples showing how to get the actual pixel point that was clicked:
https://github.com/nrkn/object-fit-math

CSS convert percentage to pixel

I know my question may sound odd but I was wondering if there was a way to convert CSS percentage into pixels. My goal with this is to calculate widths and heights with percentage values but not have them change when the screen is resized. If there is another way to achieve my goal I would be glad to hear it.
you can do it using javascript.
you get the width of the current width of the element and then set that width to the element.
var wid = document.getElementById("mydiv").offsetWidth;
wid+="px"
this returns the width in pixels and you append the "px" to the returned numerical value
and then you can set it as below
getElementById("mydiv").setAttribute("style",'width:wid');
you can fix the width of the document at once in the beggining
$(document).ready(function() {
var screenWidth = $(window).width();
$('html,body').css('width', screenWidth + 'px');
});

Getting a Image to Resize Responsively Before It's Edges Are Reached in Bootstrap 3

I have a small image in my project that I would like to resize responsively any time the resolution changes. I am currently using the class "img-responsive". With this class, the picture doesn't start resizing until the window reaches its edge. In this case, since it's a relatively small picture, this never happens.
Is there a built-in Bootstrap class I can use to have the image resize responsively at all times?
I ended up using JavaScript
$(window).resize(function(){
if($(window).width() < 1100){
var width = $(window).width();
var ceiling_width = 1100;
var difference = ceiling_width - width;
var decrease = difference * 0.2345;
var full_logo_width = 404;
var new_logo_width = full_logo_width - decrease;
$("#my_logo").css({"width": new_logo_width});
}
});
If the browser's width gets lower than 1100px then the picture will start shrinking. My image has a width of 404px by default (if the browser loads with a width of more than 1100px). I wanted the smallest possible width for the image to be a little over 200px. The per pixel decrease to per window width decrease variable (0.2345 in this case) was calculated based on this. I used the following CSS to set an upper and lower limit for the image's width.
#my_logo{
max-width: 404px;
min-width: 210px;
}

HTML5 Canvas fills windows with full resolution

I am trying to achieve a layout like this:
where:
Navbar is just a bootstrap-like top menu, 60px of height, always on top
Pop-up menu is fixed in that position (not always visible), always on top
The entire free area (windows w.o. navbar) is filled with Canvas.
Live example: jsFiddle
I have a problem with Canvas. I currently have a simple style:
<canvas id="le_canvas">Y U NO CANVAS</canvas>
...
#le-canvas {
position:absolute;
width:100%;
height:100%;
}
and the canvas is filling the background, but:
the resolution is very low
it doesn't maintain ratio during window resizes.
What I'd like (if it is possible):
full resolution of the area to fill (1:1 pixel on canvas and on screen)
set the ratio of the area to fill
bonus: update the above after window resize
Setting the canvas element in per-centage will not set the actual canvas size which must be set in absolute pixels. What happens here is that you get a canvas with a default size which then is stretched by the html-rendering giving the blurry look.
You therefor need to set the size by using f.ex. the window's sizes in absolute pixels.
You can do this like this (update of fiddle here: http://jsfiddle.net/x5LpA/3/ ) -
Create a function that sets the canvas size based on window size (you will of course need to subtract height of bars etc, but to show the principle):
function initCanvasArea(cnv) {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
}
As the canvas content are cleared when the canvas is re-sized you need to render the content again for each time. Therefor it will be smart to extract the render content into a separate function like f.ex:
function renderCanvas(ctx) {
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(0, 0, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect(20, 20, 55, 50);
}
Now, make the main function a self-invoking one where you also attach an event handler for windo.resize to update the canvas:
$(function () {
var canvas = $('#le_canvas')[0];
var ctx = canvas.getContext('2d');
initCanvasArea(canvas);
renderCanvas(ctx);
window.onresize = function(e) {
initCanvasArea(canvas);
renderCanvas(ctx);
};
})();
And finally edit the CSS-rule by removing the width/height set to 100%;
#le_canvas {
position:absolute;
}
(Tip: a better approach here is to use the fixed attribute for position - plus use a wrapper element, padding, box-sizing.. but that is out of scope for this question).
Is this what you are after? I used $(document).width() and $(document).height() to get the width and height for the rectangle. http://jsfiddle.net/x5LpA/1/

How can I autoscale the font size to fit the contents of a div?

I have a div with some text:
<div style="white-space:nowrap;overflow:none;width:50px;">
With some text in it
</div>
How can I scale the font size of the text so all of the text is visible?
Contrary-wise. You could wrap the text in an interior DIV, measure its width with JavaScript. Test if that width is wider than the parent DIV. Get the current font size, and incrementally move it down 1px at a time until inner DIV's width is less than or equal to the outer DIV's width.
I've been doing something like this, to set the text scale relative to the parent (or window) width / height. You can avoid jQuery by using offsetWidth and offsetHeight instead of width.
var setBodyScale = function () {
var scaleSource = $(window).width(), // could be any div
scaleFactor = 0.055,
maxScale = 500,
minScale = 75; //Tweak these values to taste
var fontSize = (scaleSource * scaleFactor) - 8; //Multiply the width of the body by the scaling factor:
if (fontSize > maxScale) fontSize = maxScale;
if (fontSize < minScale) fontSize = minScale; //Enforce the minimum and maximums
$('html').css('font-size', fontSize + '%'); // or em
}
Short Answer: You don't.
You would have to try a size, render it, see if it fits, try another size, render it see if it fits, etc. Then you have to handle the case where the calculated font size is so small no one can read the text.
There are other options, if the text doesn't fit, add an ellipsis (...) to the end of the text, when you mouse over it, the div could expand, you could use a popup window or tooltip with the full text, or put the full text in a larger area of the screen.
Find another way.
Came across this JQuery plugin in my quest to find the same.
Github
Demo
Also came across this Jquery script when I was looking for the same thing. It has the added benefit over the others, as far as I quickly tell, is that it also adjusts for height as well as width.
Comes from here: http://www.metaltoad.com/blog/resizing-text-fit-container
function adjustHeights(elem) {
var fontstep = 2;
if ($(elem).height()>$(elem).parent().height() || $(elem).width()>$(elem).parent().width()) {
$(elem).css('font-size',(($(elem).css('font-size').substr(0,2)-fontstep)) + 'px').css('line-height',(($(elem).css('font-size').substr(0,2))) + 'px');
adjustHeights(elem);
}
}

Resources