How to Position UI Elements on Background Image Relative to the Image

How to position UI elements on background image relative to the image

You can solve this a few ways:

  • Compute the final x/y position manually based on current screen dimension and "design" dimension
  • Manually create aspect-ratio based constraints and let iOS compute the final position for you

Assuming that your device/app orientation is constant (always landscape or always portrait) and is always fullscreen, it may be easier to compute it by hand.

First, you will need a helper function to resize your image:

private func scaledImage(named imageName: String, scale: CGFloat) -> UIImage? {
guard let image = UIImage(named: imageName) else { return nil }
let targetSize = CGSize(width: image.size.width * scale, height: image.size.height * scale)
return resizeImage(image: image, targetSize: targetSize)
}

// Adapted from https://stackoverflow.com/questions/31314412/how-to-resize-image-in-swift
private func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage? {
let size = image.size

let widthRatio = targetSize.width / size.width
let heightRatio = targetSize.height / size.height

// Figure out what our orientation is, and use that to form the rectangle
var newSize: CGSize
if(widthRatio > heightRatio) {
newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
} else {
newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
}

// This is the rect that we've calculated out and this is what is actually used below
let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)

// Actually do the resizing to the rect using the ImageContext stuff
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
image.draw(in: rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}

Next, we will create a function to compute the location of the button, and the size of the button based on the image size:

private func positionScaledButton(x designX: CGFloat, y designY: CGFloat, imageName: String) -> UIButton {

// First, compute our "designScale"
let screenHeight = UIScreen.main.bounds.size.height
let backgroundDesignHeight: CGFloat = 330.0 // ** see below
let designScale = screenHeight / backgroundDesignHeight

// Create button
let button = UIButton(type: .custom)

// Get image to use, and scale it as required
guard let image = scaledImage(named: imageName, scale: designScale) else { return button }

button.frame = CGRect(x: designX * designScale, y: designY * designScale, width: image.size.width, height: image.size.height)
button.setImage(image, for: .normal)
scrollView.addSubview(button)
return button
}

** The value "330.0" in the code above refers to the height of the background image in the scroller, from which the x/y coordinates of the button were measured.

Assuming button's top-left corner should be at x: 10, y: 10, for image "levelOne":

let levelOneButton = positionScaledButton(x: 10, y: 10, imageName: "imageOne")
// To do: addTarget event handler

Position 4 background image on top, left, right and bottom

You can use clip-path for the shapes, along with some absolute positioning and flex displays.

* {
padding: 0;
margin: 0;
box-sizing: border-box;
font-size: .9rem;
}

#main {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
background: white;
height: 100vh;
position: relative;
}

#left {
flex: 1;
height: 80%;
background: blue;
clip-path: polygon(0% 0%, 75% 0%, 100% 50%, 75% 100%, 0% 100%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

ul li {
list-style: none;
}

#sect {
flex: 2;
display: flex;
justify-content: center;
padding: .5rem;
}

#right {
flex: 1;
height: 80%;
background: blue;
clip-path: polygon(25% 0%, 100% 0%, 100% 100%, 25% 100%, 0% 50%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

#top {
display: flex;
align-items: flex-start;
justify-content: center;
background: #ddd;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 20vh;
clip-path: polygon(100% 0, 100% 77%, 50% 100%, 0 77%, 0 0);
}

#bottom {
display: flex;
align-items: flex-end;
justify-content: center;
background: #ddd;
position: absolute;
bottom: 0;
left: 0;
width: 100vw;
height: 20vh;
clip-path: polygon(50% 1%, 100% 23%, 100% 100%, 0 100%, 0 23%);
}
<div id="main">
<!-- absolutely positioned elements for top and bottom
placed on top so z-index is behind following content-->
<div id="top">This is the top section</div>
<div id="bottom">This is the bottom section</div>
<!-- main flex container starts here
Place a justify-content: space-between to space
left and right elements to far edges -->
<div id="left">
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
</ul>
</div>
<div id="sect">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
<div id="right">
<ul>
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
</ul>
</div>
</div>

Position Text after Background Image (background-size:cover)

<header>
<h1>Olivia E Thorne</h1>
<p>Brighton, UK</p>
</header>
<div class="next"> <p>Some content...</p></div>
</body>
</html>

and the CSS:

body {
background:url('header.png') #A98436 no-repeat;
-webkit-background-size: cover;
-moz-background-size: cover;
background-size: cover;
}

header{
position: fixed;
color: whitesmoke;
font-family: "Segoe UI";
font-size: 1em;
line-height: 50%;
top: 35%;
left: 45%;
z-index: 100;
}
.next{
position:relative;
top: 500px; (or 50% or whatever the height of the pic is)
}

css background image positioning (negative position?)

The background image is within the box so moving it outside is not feasible like this. What you could do is position your image outside of the box and move it into it.

You can try something like this, it's not foolproof but can get you some of the way there.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<style type="text/css">
body {
background-color:#26140C;
}

.box {
width: 800px;
margin: 0 auto;
margin-top: 40px;
padding: 10px;
border: 3px solid #A5927C;

background-color: #3D2216;
}

.image {
float: left;
position: relative;
top: -30px;
}
</style>
</head>
<body>
<div class="box">
<img src='icon_neutral.png' class="image" />
<h1>This is a test!</h1>
</div>
</body>

background-image in react component

I've found a fix for my case. Actually setting container height in pixels have helped.

Here's the code:

import React from 'react';

const styles = {
paperContainer: {
height: 1356,
backgroundImage: `url(${"static/src/img/main.jpg"})`
}
};

export default class Home extends React.Component {
render() {
return (
<div style={styles.paperContainer}>
</div>
)
}
}

Not able to add Background Image on Position Absolute div

Because #img-box has not any width & heights associated with it. try to define

html, body {    height:100%;    width:100%;}#wrapper {    position: relative;    height: 100%;    width: 100%;}#img-box {    position: absolute;    background-image: url("http://www.clker.com/cliparts/2/0/f/b/13873752061098664878happy_smiley-th.png");    height: 100%;    width: 100%;    top:0;    left:0;    background-size: cover;    background-repeat: no-repeat;    background-attachment: fixed;}
<div id="wrapper">    <div id="img-box"></div>    <div id="tets"></div>    <div id="tes3"></div></div>

Background image clipped to draggable div

If I understand your requirements correctly, you can do this by finding the current position of the draggable object as it moves, and then using those values to set the background-position of the screen's background, giving a sort of x-ray glasses effect.

var imageOffset = {
top: 30,
left: 32
};

$(function() {
var screenHeight = $('body').height() - 300; // 300: moa height

$(".screen").css('background-position', -(imageOffset.left) + 'px ' + -(screenHeight + imageOffset.top) + 'px');

$(".mao").draggable({
axis: "x",
drag: function(event, ui) {
$(".screen").css('background-position', -(ui.position.left + imageOffset.left) + 'px ' + -(ui.position.top + imageOffset.top) + 'px');
}
});
})

Example Codepen: http://codepen.io/anon/pen/JWxwzK?editors=0000

You can also use the same piece of code to constrain the hand to the left/right boundaries of the screen. There's an example of code to do that in the official docs: http://api.jqueryui.com/draggable/#event-drag



Related Topics



Leave a reply



Submit