I'm trying to fill a div (black area in following screen) with an img.
But the scale of image should not change.
And when the size of the div changes according to the size of the browser, the image should be displayed by adjusting the width or adjusting the height accordingly.
The image changes dynamically, so I never know if it will be tall or long.
for example
Finally, the target is to make the image show as large as possible without changing the scale of the image.
Below is the code I developed.
<div className="asset__item">
<a className="asset__img">
<img
alt="item image"
src="/img/1.jpg"
/>
</a>
</div>
CSS
.asset__item {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
position: relative;
padding: 20px 20px 20px 20px;
width: 100%;
border-radius: 16px;
margin-top: 20px;
background: #202020;
}
.asset__item img {
width: auto;
max-width: 100%;
}
Please let me know how to fix it.
I try not to modify the styles of asset__item as much as possible.
But it's ok to add a div there instead.
You can try using object-fit :
`
img{
width: auto;
max-width: 100%;
object-fit:cover;
}
`
I could not find a way to do it using only CSS. So I directly assigned width and height to my image using JavaScript. We should handle 4 different situations:
Album picture and album screen
Album picture and portrait screen
Portrait picture and album screen
Portrait picture and portrait screen
My imgObj contains initial width and height of the image (I got them using react-image-size).
And here is the code:
const imageObj = useSelector((state) => state.imageHandling.imageObj);
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const handleImageSize = () => {
if (imageObj) {
let w = 0;
let h = 0;
const ratio = imageObj.width / imageObj.height;
const theSameTypes = () => {
w = window.innerWidth;
h = window.innerWidth / ratio;
if (h > window.innerHeight) {
h = window.innerHeight;
w = h * ratio;
}
};
if (imageObj.width > imageObj.height) {
if (window.innerWidth > window.innerHeight) {
theSameTypes(); //album picture and album screen
} else {
w = window.innerWidth; //album picture and portrait screen
h = w / ratio;
}
} else {
if (window.innerWidth > window.innerHeight) {
h = window.innerHeight; // portrait picture and album screen
w = h * ratio;
} else {
theSameTypes(); // portrait picture and portrait screen
}
}
setWidth(w);
setHeight(h);
}
};
useEffect(() => {
window.addEventListener("resize", handleImageSize);
return () => {
window.removeEventListener("resize", handleImageSize);
};
}, []);
useEffect(handleImageSize, [imageObj]);
Related
I want to bind text font-size with text length (in <p> with fixed width for example). Expected result is text fit in one line if it is only one word. If there are few words, it can be few lines.
I want to reduce font-size if word is too long for fixed-width line. For example, if "abc" fit in line I want to do nothing, if "abcdefg" doesn't fit in line I want to reduce text font-size
You can use a simply div setting your personal width, inside set your text, in css use
display: flex;
flex-wrap: wrap;
That way the text will respect your div width and brake line in your text when necessary
flex-wrap
Hope this answer will satisfy your question.
The resizing part, which is the most important, is creditted to Jan Küster, with "Make text fit its parent size using JavaScript" article that you can find online.
document.getElementsByTagName("input")[0].onkeyup = execute;
function execute() {
let value = document.getElementsByTagName("input")[0].value;
let words = value.split(" ");
var html = "";
for (var i = 0; i < words.length; i++) {
html += ' <div class="text-container"><span class="text">' + words[i] + '</span></div>';
document.getElementsByClassName("parent")[0].innerHTML = html;
}
resizeText({
elements: document.querySelectorAll('.text'),
step: 0.25
})
}
//
const isOverflown = ({
clientWidth,
clientHeight,
scrollWidth,
scrollHeight
}) => (scrollWidth > clientWidth) || (scrollHeight > clientHeight)
const resizeText = ({
element,
elements,
minSize = 10,
maxSize = 512,
step = 1,
unit = 'px'
}) => {
(elements || [element]).forEach(el => {
let i = minSize
let overflow = false
const parent = el.parentNode
while (!overflow && i < maxSize) {
el.style.fontSize = `${i}${unit}`
overflow = isOverflown(parent)
if (!overflow) i += step
}
// revert to last state where no overflow happened
el.style.fontSize = `${i - step}${unit}`
})
}
body {
background: #A33;
}
.parent {
margin: 2%;
width: 150px;
height: auto;
min-height: 50px;
padding: 15px;
color: white;
display: block;
}
.text-container {
width: 100%;
height: 100%;
}
.text {
font-size: 12px;
display: block;
}
<input type="text">
<div class="parent">
</div>
You could check out Bootstrap 5, they now have responsive text incorporated.
You could also use media queries that change the text size when the screen size is smaller or larger:
/* If the screen size is 601px wide or more, set the font-size of div to 80px */
#media screen and (min-width: 601px) {
div.example {
font-size: 80px;
}
}
/* If the screen size is 600px wide or less, set the font-size of <div> to 30px */
#media screen and (max-width: 600px) {
div.example {
font-size: 30px;
}
}
A final option would be to use the viewport width as the font size. Viewport is the browser window size. 1vw = 1% of viewport width. If the viewport is 50cm wide, 1vw is 0.5cm. Here's an example:
<h1 style="font-size:8vw;">Hello World</h1>
<p style="font-size:2vw;">Resize the browser window to see how the font size scales.</p>
Is possible to get "10vw" for the element width in browser or extension.Chrome "Copy Styles" just works fine.But I wanna do it in an extension.
Source code for chrome devtools
<style>
div { width: 10em }
body div { width: 10em }
#id { width: 10vw }
</style>
<div id="dom"></div>
// if viewport width is 375px
var dom = document.getElementById('app');
var style = window.getComputedStyle(dom);
var width = style.getPropertyValue('width');
console.log(width) // 37.5px, "10vw" would be great
var element = document.getElementById('dom')
var elementWidth = getComputedStyle(element ).width
this will always return width with pixels.
hope this will be helpfull
I'm trying to make a circle out of images with different sizes and different shapes (some rectangle, some sqaure, some portrait, some landscape).
When I'm using: clip-path: circle(50% at 50% 50%); or border-radius: 50%;, it turns the image into a perfect circle, only if the image is square:
Is there a way to crop an image into a square and then use one of these methods to make it a perfect circle:
Using pure CSS withou using background-image (most images are given the background image from server side),
Keeping a 50% ratio - without losing aspect ratio - (both if border-radius or clip-path)(Images size may vary).
Here's a code snippet to show a square image and a rectangle image:
.clipped {
clip-path: circle(50% at 50% 50%);
}
Square<br>
<img src='http://i.imgur.com/d5byNNR.jpg' width="100" class='clipped' /><br><br>
Rectangle<br>
<img src='http://i.imgur.com/22W12EQ.jpg' width="100" class='clipped' />
You can use circle() but without the parameters:
.clipped {
clip-path: circle();
}
It appears to use the smaller side of your image as the circle's circumference.
Working sample here.
It works on Chrome and FireFox. IE and Edge still does not support clip-path
That's an another way to do it using pure CSS:
HTML
<div class="circular--portrait">
<img src='http://i.imgur.com/22W12EQ.jpg'/>
</div>
CSS
.circular--portrait {
position: relative;
overflow: hidden;
width: 100px;
height: 100px;
border-radius: 50%;
}
.circular--portrait img {
width: 100%;
height: auto;
margin-top: -30px;
}
Code Snippet (with portrait and landscape examples)
Alright, took me a moment but this is what I came up with:
function ScaleImage(srcwidth, srcheight, targetwidth, targetheight, fLetterBox, xOffSet, yOffSet) {
var result = { width: 0, height: 0, fScaleToTargetWidth: true };
if ((srcwidth <= 0) || (srcheight <= 0) || (targetwidth <= 0) || (targetheight <= 0)) {
return result;
}
// scale to the target width
var scaleX1 = targetwidth;
var scaleY1 = (srcheight * targetwidth) / srcwidth;
// scale to the target height
var scaleX2 = (srcwidth * targetheight) / srcheight;
var scaleY2 = targetheight;
// now figure out which one we should use
var fScaleOnWidth = (scaleX2 > targetwidth);
if (fScaleOnWidth) {
fScaleOnWidth = fLetterBox;
}
else {
fScaleOnWidth = !fLetterBox;
}
if (fScaleOnWidth) {
result.width = Math.floor(scaleX1);
result.height = Math.floor(scaleY1);
result.fScaleToTargetWidth = true;
}
else {
result.width = Math.floor(scaleX2);
result.height = Math.floor(scaleY2);
result.fScaleToTargetWidth = false;
}
//result.targetleft = Math.floor((targetwidth - result.width) / 2);
//result.targettop = Math.floor((targetheight - result.height) / 2);
result.targetleft = Math.floor((targetwidth - result.width) / 2 - xOffSet);
result.targettop = Math.floor((targetheight - result.height) / 2 - yOffSet);
return result;
}
function OnImageLoad(evt, xOffSet = 0, yOffSet = 0) {
var img = evt.currentTarget;
// what's the size of this image and it's parent
var w = $(img).width();
var h = $(img).height();
var tw = $(img).parent().width();
var th = $(img).parent().height();
// compute the new size and offsets
var result = ScaleImage(w, h, tw, th, false, xOffSet, yOffSet);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
$(img).css("left", result.targetleft);
$(img).css("top", result.targettop);
}
.result {
width: 250px;
height: 250px;
border: thick solid #666666;
overflow: hidden;
position: relative;
border-radius: 50%;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
No offset:
<div class='result'>
<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 0);"/>
</div>
Y offset:
<div class='result'>
<img src="http://i.imgur.com/22W12EQ.jpg" style="position: absolute;" onload="OnImageLoad(event, 0, 30);"/>
</div>
I took most of the work from this resource: https://selbie.wordpress.com/2011/01/23/scale-crop-and-center-an-image-with-correct-aspect-ratio-in-html-and-javascript/ and I've adepted it to allow the use of Offsets so you can crop any image at the position you want.
How it works
You create a div of any size you want. It can be square, but if you want an egg-like result, that works as well (lol). Then insert the image of any unknown size inside it.
Change onload="OnImageLoad(event, 0, 30); with the offsets you want. Positive offsets for moving the image left or down, negative for up or right.
Note: I did use jQuery for this.
i set a div's width 100% in css, it initial ok in portrait mode.i rotate my iphone to landscape mode , and then switch to portrait mode.unfortunately the page render in disorder,it appear that the div is zoom out. The problem page is showed as follow:
The page contains two parts, the image area's width and height are set via JavaScript, blow the image is the div i mentioned before, it seems zoom out after roating from landscape to portrait mode.I have put the meta tag viewport in head ,which is set as
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
I think i have find the answer to this question.Because my code is so complex, i simplify it as follows:
<div class="wrapMv clearfix" id="playArea">
<div class="mv" id="playerContainer">
<div class="mvPlayer" id="mvPlayer">
<!--<video id="player" src="" autoplay controls></video>-->
<div id="posterImgDiv" class="poster-img-div">
<img id="postImg" class="poster-img" src="">
</div>
</div>
</div>
</div>
<div id="main" class="main clearfix">
<div style="height: 10px;"></div>
<div id="sayContent" class="sayContent">
<h3>大家都在说</h3>
<ul id="chatArea">
</ul>
</div>
</div>
this is the html code.
var player = {
init : function() {
var ua = navigator.userAgent.toLowerCase();
this.isIos = (/(iphone|ipad|ipod)/i).test(ua);
if (this.isIos) {
this.iosVersion = this._getIOSVersion(ua);
}
this.canUseNativeFullApi = (/(qqbrowser|ucbrowser|micromessenger)/i).test(ua);
this.isModenBrowser = this.isIos | this.canUseNativeFullApi;
this._initPlayerDom();
},
_getIOSVersion : function (ua) {
if (/cpu (?:iphone )?os (\d+_\d+)/.test(ua)){
return parseFloat(RegExp.$1.replace("_", "."));
} else {
return 2;
}
},
_orientationChangeHandler : function() {
var self = this;
setTimeout(function() {
var isLandscape = false;
if ( window.orientation == 180 || window.orientation== 0 ) {
$('body').removeClass('landscape');
window.scrollTo(0, 0);console.log('竖屏');////
} else if( window.orientation == 90 || window.orientation == -90 ) {//横屏
$('body').addClass('landscape');
isLandscape = true;
}
self.resizePlayer(isLandscape,true);//
}, 300);
},
_addOrientationListener : function() {
var self = this;
if (this.isModenBrowser) {console.log('use orientationchange');
window.addEventListener('orientationchange', function(){
self._orientationChangeHandler();
});
} else {console.log('use resize event');
$(window).resize(function() {
self._orientationChangeHandler();
});
}
},
_initPlayerDom : function() {
this._addOrientationListener();
var $player;
$('#mvPlayer').append( '<video x-webkit-airplay="allow" webkit-playsinline id="player" ></video>');
$player = $('#player');
this.$player = $player;
},
resizePlayer : function(isLandscape,noNeedResizeChatContent) {
var self = this;
var currentInnerHeight = window.innerHeight;
var playerWidth = window.innerWidth;
var playerHeight = playerWidth * 9 / 16;
if (playerHeight > currentInnerHeight) {
playerWidth = currentInnerHeight * 16 / 9;
playerHeight = currentInnerHeight;
}
setTimeout(function() {
$('#playerContainer').height(playerHeight).width(playerWidth);
$('#player').height(playerHeight).width(playerWidth);
},10);
}
};
This is the js code.The key point of this problem is hide in the function of resizePlayer. Let see the code var playerWidth = window.innerWidth; and $('#player').height(playerHeight).width(playerWidth);,when you rotate your iphone ,the video's height and width will be recumputed.After I debug my page via weinre, i found that when switch from landscape to portrait,the value of window.innderWidth got from ios9 war wrong and always bigger than factual value.
The style set in css :
.mv{
margin: 0 auto;
width: 100%;
}
.mvPlayer{
margin: 0 auto;
width: 100%;
}
.main{
overflow-y: scroll;
width: 100%;
height: auto;
display: inline-block;
}
Finally ,i resolved the problem.I add a style in css:
.mvPlayer video {
width: 100%;
}
And not set the width of the player in javascript:
$('#playerContainer').height(playerHeight);
$('#player').height(playerHeight);
I'm trying to create a page layout like This
But I am not sure how to achieve it. What I mean; in that page you can see there are two areas in the page and you can resize the areas using the bar between them.
Thanks!
Yes, it's certainly possible. There's probably a JQuery or MooTools plugin out there that does it. Otherwise, I rolled you a simple example using JQuery that you can play with. See this JSFiddle.
Basically the HTML is like this:
<div id="left">Left column!</div>
<div id="verticalresizer"> </div>
<div id="right">Right column!</div>
And then they are positioned absolutely (extra CSS from example cut for simplicity's sake):
html, body {
height: 100%;
}
#left {
width: 200px; /* default starting width */
position: absolute;
top: 0;
bottom: 0;
left: 0;
}
#right {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 204px; /* width of left col + 4 pixel wide resizer */
}
#verticalresizer {
background-color: black; /* so it can be seen */
width: 4px;
height: 100%;
cursor: col-resize;
position: absolute;
top: 0;
left: 200px; /* width of left col */
bottom: 0;
}
Then the JavaScript. First an explanation. Pretty much the code listens for the user to click down on the vertical resizer. Once that happens, it listens for the mouse moving. Every time the mouse moves, resize the columns accordingly and keep the slider underneath the mouse. When the user lets go of the mouse (mouseup), stop listening/resizing.
var left = 200; // starting left col width
var isClicked = false;
var startX = 200; // starting horizontal position of resizer bar
var isMouseDown = false;
// attach listeners to the document itself
$(document).mousedown(function() {
isMouseDown = true;
}).mouseup(function() {
isMouseDown = false;
}).mousemove( function(event) {
if (isClicked && isMouseDown) {
var newX = event.pageX;
if (startX != newX) {
left += (newX - startX);
if (left < 0) {
left = 0; // keep from moving the slider beyond the left edge of the screen
newX = 0;
}
setWidthOfLeftColumn( left );
startX = newX;
}
}
});
// attach click listeners to the resizer slider
$("#verticalresizer").mousedown( function(event) {
isClicked = true;
startX = event.pageX;
}).mouseup( function (event) {
isClicked = false;
});
// function to resize everything
function setWidthOfLeftColumn( value ) {
$("#left").css("width", "" + left + "px");
$("#right").css("left", "" + (left + 4) + "px");
$("#verticalresizer").css("left", "" + left + "px");
}
Try using the HTML frameset tag.
http://www.w3schools.com/tags/tag_frameset.asp