I created a regular image in HTML. Then, dynamically via JavaScript, I added an image within the initial image. However, I am having an issue where if a user were to zoom in or out, the internal image does not stay in the same place. And it is possible that a user could zoom in my case, anytime, and I really need the internal image not to move. I do not have anything fancy, and I am trying all sorts of ways to get this to work, so if you have a way that uses HTML and CSS, I could add it to my code, because I have tried many different avenues and changed my HTML around multiple times. However, if you would like my code, in depth, I would be glad to supply it with you. Any help is greatly appreciated, or if you simply need more clarification, I can do that as well, thanks in advance.
Here is an example of the code that adds an image to an image, and has the issue that I explained above:
$(document).ready(function() {
$('#myImgId').click(function(e) {
var offX = event.clientX;
var offY = event.clientY;
margin = 20;
if (offX > margin) offX -= margin;
if (offY > margin) offY -= margin;
var signHereImage = document.createElement("img");
signHereImage.setAttribute('src', 'imageInserted.jpg');
signHereImage.setAttribute('class', 'overlays');
signHereImage.style.left = offX + "px";
signHereImage.style.top = offY + "px";
document.body.appendChild(signHereImage);
});
});
<form id="form1" runat="server">
<div>
<img src="page3.jpg" alt="PDF Image" id="myImgId" />
</div>
</form>
This is for the most part what it is, I know that I am doing something incorrectly, I just do not know what for certain, thanks again in advance.
I would use the background-image property to achieve this. You can place the image in a div, give that div a background image, and then position the image relative to the div. Here's a working example:
div {
position: relative;
height: 500px;
background-image: url(https://images.unsplash.com/photo-1413781892741-08a142b23dfe?dpr=2&auto=format&fit=crop&w=1500&h=1000&q=80&cs=tinysrgb&crop=&bg=);
background-size: cover;
}
img {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
right: 0;
left: 0;
width: 200px;
}
<div>
<img alt="img" src="https://images.unsplash.com/photo-1483086431886-3590a88317fe?dpr=2&auto=format&fit=crop&w=1500&h=2247&q=80&cs=tinysrgb&crop=&bg=" />
</div>
Consider what changes when a user zooms in or out on a web page. The viewport size changes, relative to the content on the page.
You are probably styling the internal image based on something related to the viewport. The automatic width of block elements is calculated from the width of the viewport if other constraints are not available. For example, an element with the following CSS properties moves around with the right edge of the viewport:
position: absolute;
right: 20px;
See a demo.
Other elements, perhaps including the external image of yours, are by default laid out line-by-line, starting from the top left. This discrepancy can cause some elements of the page to move with respect to others when zooming or resizing the window.
Review how you instruct the browser to lay out these two images, and make sure that, if they depend on the size of the viewport, they depend on it in the same way.
Related
There's a lot of information on the web about this, but I really can't seem to find any exact answer that I need for my scenario - I've tried basically every combination of CSS I've found in tutorials and nothing's working.
Here's a couple of screenshots of what I'm facing (notice the markers):
Full resolution (1080p):
Shrunk browser window: (tablet)
You can see the markers are all over the place. I want these to stay relative, so the "marker" should stay above the word "great", even when the page resolution changes.
Here's my CSS, note that I've tried setting the overlay to position: absolute, with the pins as relative positioning. I've tried setting the top and left values as percentages for the markers, I can't seem to get anything to work.
.overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 9997;
background-color: rgba(0,0,0,0.5);
display: none;
}
.overlay-inner {
width: 100%;
height: 100%;
position: absolute;
}
.pp_pin_dropped {
width: 48px; // tried as percentages, position: absolute is set on the elements in JQuery - will be moved to CSS
height: 48px;
z-index: 9998;
cursor: pointer;
background-image: url('/Images/pin_dropped.png');
}
And, finally, you can see this on the following URL: http://pintool.azurewebsites.net/ (click on the bottom right hand side icon to see the markers)
I know it's asking a lot, I just hope there's some CSS guru out there that I can point me in the right direction before I pull all my hair out.
Yikes, this is going to be very difficult to do using strictly CSS and HTML. I think you're going to need to use JS for this behavior. The jQuery UI position library will come in very handy for finding your marker locations: http://jqueryui.com/position/.
Here's one idea:
I'd wrap every "keyword" on the page in a span with a unique ID. For example:
<div>some text here <span id="pos">pos</span></div>
<img src="marker.png" id="pos_marker"/>
Then on window resize, reposition your images:
$( window ).resize(function() {
$("#pos_marker").position({my: "bottom center", at: "top center", of: "#pos"});
// and so on
});
you could wrap the targeted words or characters with a span tag and then use jQuery (or javascript) to locate them on the page.
perhaps this question would be helpful too: jQuery x y document coordinates of DOM object
When you locate the specific words, just use javascript to relocate the pins. And don't forget to reposition the pins on window resize.
I think you could treat them similar to how tooltips are done, embedding the pins directly as elements like
<span data-content="Great" class="pin"></span>
then use javascript to display the icon based on the element position and redraw it when the window is resized.
<script>
function drawpins() {
$(".pin").each(function(){
pos = this.position()
pin = this.data("content");
pin += '<img src="tooltip.jpg"'
pin += 'style="position:absolute;'
pin += 'top:' + pos.y + ';'
pin += 'left:'+ pos.x + ';'
this.html(pin)
})
}
$(window).resize(drawpins())
</script>
WARNING Not TESTED, just concept
this is your problem:
element.style {
left: 872px;
position: absolute;
top: 154px;
}
I could be missing something here (I'm by no means an expert with HTML or CSS and have only just started using fabric).
It would seem that fabric is a nice tool for creating shape (object) based drawing applications but I can't figure out how to use it in such a way that a user can't lose objects by placing them off the canvas.
none of the demos have any functionality to prevent this but this seems like it would be a massive limitation to the framework. does anybody know of a way of solving this?
essentially, I want to allow users to arbitrarily add objects to the canvas and for usability, these objects will have to be spaced out and so the canvas will have to be potentially infinite. Obviously, the interaction area for the canvas will have to be of a fixed size.
Any help to get this sorted would be much apreciated
Adding to Benicks answer - you can call the canvas.on("object:moving", function(e) {}) which is triggered when an object is moved. So the wrapper will have the follwing css:
#wrapper{
position: absolute;
overflow: auto;
max-height: 600px;
max-width: 800px;
}
with an index file:
<div id="wrapper">
<canvas id="c2"></canvas>
</div>
To expand the canvas as an object is dragged to the edge of the wrapper you can do the following(done in coffee script):
canvas.on "object:moving", (e) ->
currentCanvasHeight = canvas.height
currentCanvasWidth = canvas.width
# e.target returns the selected canvas object
# Once the objects offset left value + the objects width is greater than the canvas
# width, expand the canvas width
if (e.target.left + e.target.currentWidth) > currentCanvasWidth
canvas.setWidth currentCanvasWidth + 50
$("#wrapper").scrollLeft e.target.left # scroll alongside the canvas expansion
$('#wrapper').on 'scroll', canvas.calcOffset.bind(canvas) # to fix the mouse
#position bug issue
# do the same for the top
if (e.target.top + e.target.currentHeight) > currentCanvasHeight
canvas.setHeight currentCanvasHeight + 50
$("#wrapper").scrollTop e.target.top
$('#wrapper').on 'scroll', canvas.calcOffset.bind(canvas)
we sort of had the same problem and solved by creating a viewport. We created a div around the canvas div.
<div id="viewport">
<div id="canvas"></div>
</div>
CSS:
#viewport {
height: 500px;
left: 0;
position: absolute;
top: 0;
width: 500px;
overflow: auto;
}
JS to create the canvas:
var canvas = new fabric.Canvas('canvas');
canvas.setWidth(1000);
canvas.setHeight(1000);
canvas.renderAll();
Now you should be able the scroll through the canvas. However you will realize that your mouseposition is not correct anymore. You can fix that using the canvas.calcOffset() method and bind it to the scroll event of the viewport for example.
Hope this helps.
I'm using SuperScrollorama to trigger a lot of animations on a single page (scrolling) website. All of the images and text that slide in from the left or right work perfectly. The problem is when I try to make an image drop in from the top of the screen the image will bounce up and down the whole time the user scrolls until they finally get down to the point where the image is supposed to "sit" (It basically goes back to it's original position and then down to where it's supposed to stay and then back up again and so on)... Here's my relevant code:
HTML:
<div id="about-pin-div">
<div id="pin-frame-pin" class="pin-frame"><img src="img/about-products.png" style="width: 55%;"></div>
</div>
CSS:
#about-pin-div { position: relative; width: 100%; height: 100%; left: -5%; overflow: hidden; }
.pin-frame { position: absolute; width: 100%; height: 100%; overflow: hidden; }
.pin-frame img { margin-top: -200px; }
JAVASCRIPT:
$(document).ready(function() {
var controller = $.superscrollorama();
controller.addTween('#about-pin-div', TweenMax.from( $('#about-pin-div'), .5, {css:{bottom:'1000px'}, ease:Quad.easeInOut}), 0, 600);
// set duration, in pixels scrolled, for pinned element
var pinDur = 1000;
// create animation timeline for pinned element
var pinAnimations = new TimelineLite();
pinAnimations
.append(TweenMax.from($('#pin-frame-pin img'), .5, {css:{marginTop:80}}))
// pin element, use onPin and onUnpin to adjust the height of the element
controller.pin($('#about-pin-div'), pinDur, {
anim:pinAnimations,
onPin: function() {
$('#about-pin-div').css('height','100%');
},
onUnpin: function() {
$('#about-pin-div').css('height','100%');
}
});
});
Thanks in advance for any help!
I think you are having a number of issues here and I will try to point out some problems that I have had with this plugin.
(1) When in doubt turn off pushFollowers for your pins.
In an effort not to continue to repeat myself
Play through pinned elements in superscrollorama
janpaepke did an excellent job in writing this work around because he had the same issues himself.
(2) Never use margins for adjusting the position, IE handles margins badly sometimes depending on the context won't work the way you want it to.
When to use margin vs padding in CSS
Does a better job at explaining it then I can.
(3) I don't understand the need to trigger on pin functions to adjust the height of #about-pin-div. You are just resetting the starting value over and over that I don't see ever gets changed. Unless you were trying to compensate for the automatically adjusting of pinned elements but the work around in (1) should fix that.
Here's a link to what I'll be referring to.
I'm having some trouble getting the background image to work the way I'd like it to.
I want the background to auto resize based on the width of the window, which it is already doing correctly. If you make your window smaller you'll see the background shrink with it.
Here's the issue. If you make your window wide (short) then the background will resize and go too high so you can't see the top of the background anymore (since the background is bottom positioned).
I want the background to be top position when you are at the top of the page, and as you scroll down it will slowly move to be bottom positioned. Sort of like the effect of an Android phone's background when you move left and right. Of course, keep in mind that I still want the background to auto-resize when you make the window smaller.
html {
background-color: #70d4e3;
height: 100%;
}
body {
height: 100%;
}
.background {
margin-top: 45px;
width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
}
.banner {
margin: 0px auto;
width: 991px;
margin-bottom: -9px;
}
.content {
background: url("http://i.imgur.com/daRJl.png") no-repeat scroll center center transparent;
height: 889px;
margin: 0 auto;
width: 869px;
}
.innerContent {
padding: 30px;
}
<img src="http://i.imgur.com/6d5Cm.jpg" alt="" class="background" />
<div class="banner">
<img src="http://i.imgur.com/JptsZ.jpg" alt="" />
</div>
<div class="content">
<div class="innerContent">
testing
</div>
</div>
Maybe some javascript or jquery would be needed to achieve this.
Well, this was fun, thanks!
I hope you don't mind me taking the liberty to use percentages to make my life a little bit easier and possibly the script slightly more robust since I can reliably use floats with percentages.
What I did is make the layout, html and css comply with the rules you need for the bg to be animated properly, they stayed largely the same from what you had.
Then it was just a question of figuring out the calculations needed with the right properties to figure out the percentage you were from the top, the *20 is actually the amount of space 'left' to fill by the background image in percentages (as the background height is 80%).
They I moved the calculations to a function so I could call that on scroll and on window resize, making sure it's initiated on any event that modifies the window somehow...
Didn't do extensive testing but it worked in Chrome and I'm tired :p
I believe this is what you are looking for:
http://jsfiddle.net/sg3s/RSqrw/15/ See edit 2
If you wanted this the other way arround just make the page background start at the top and modify that:
http://jsfiddle.net/sg3s/RSqrw/14/ See edit 2
Edit:
As a bonus, and since I had never actually written jquery script as a 'plugin', I decided to convert this into one. What I came up with should be easy to implement and use!
http://jsfiddle.net/sg3s/RSqrw/52/ See Edit 3
Functionality successfully tested in Chrome, Firefox 3.6, IE9 + compatibility mode
Edit 2:
Reading the question again checking if I did it right I noticed I didn't quite do what you want, so I updated the link in the first edit which gives you a plugin in which you can have several options for the scrolling background. It retains my 'old' interpetation while also doing what you want... Read comments in code for some extra descriptions.
Edit 3:
As I went to work today I was bothered with the fact that my plugin 'try' was a little bloated. And as you mentioned in the comment it didn't quite fit the requirements.
So I rewrote it to only do what you want and not much more, tested in Chrome Firefox, IE9 +compat etc etc.. This script is a lot cleaner.
http://jsfiddle.net/sg3s/vZxHW/
You can chose to make the background stick to the top or bottom if the height fits in the window. Nothing else, but that is already more than enough to do some pretty cool stuff :p
An exact solution: Fiddle: http://jsfiddle.net/srGHE/2/show/
View source
Thanks for the challenge. See below for the solution, which is complying with all requirements, including recommended yet optional (with steps on how to remove these) features. I only show the changed parts of your page, with an explanation after each section (CSS, HTML and JavaScript):
CSS (changes):
html,body{
margin: 0;
height: 100%;
padding: 0;
}
body{
background-color: #70d4e3;
}
#background { /*Previously: .background*/
/*Removed: margin-top: 45px;
No other changes*/
}
#banner /*Previously: .banner; no other changes */
#content /*Previously: .content; no other changes */
#innerContent /*Previously: .innerContent; no other changes */
Explanation of CSS revisions:
margin-top:45px at the background is unnecessary, since you're absolutely positioning the element.
All of the elements which are unlikely to appear more than once should be selected via the id (#) selector. This selector is more specific than the class selector.
HTML (changes):
All of the class attributes have been replaced by id. No other changes have been made. Don't forget to include the JQuery framework, because I've implemented your wishes using JQuery.
JavaScript (new):
Note: I have added a feature which you didn't request, but seems logical. The code will automatically reserve sufficient margin at the left side of the window in order to always display the background. Remove anything between the marked comments if you don't want this feature.
$(document).ready(function(){
//"Static" variables
var background = $("#background");
var marginTop = parseFloat(background.css("margin-top")) || 0;
var bannerWidth = $("#banner").width(); /*Part of auto left-margin */
var extraContWidth = (bannerWidth - $("#content").width())/2; /*Same as above*/
function fixBG(){
var bodyWidth = $("body").width();
var body_bg_width_ratio = bodyWidth/1920;
var bgHeight = body_bg_width_ratio * 926; //Calcs the visible height of BG
var height = $(document).height();
var docHeight = $(window).height();
var difHeight = bgHeight - docHeight;
var scrollDif = $(document).scrollTop() / (height - docHeight) || 0;
/*Start of automatic left-margin*/
var arrowWidth = body_bg_width_ratio * 115; //Arrow width
if(bodyWidth - bannerWidth > arrowWidth*2){
$("body > div").css("margin-left", "auto");
} else {
$("body > #banner").css("margin-left", arrowWidth+"px");
$("body > #content").css("margin-left", (arrowWidth+extraContWidth)+"px");
}
/*End of automatic left-margin*/
if(difHeight > 0){
background.css({top:(-scrollDif*difHeight-marginTop)+"px", bottom:""});
} else {
background.css({top:"", bottom:"0"});
}
}
$(window).resize(fixBG);
$(window).scroll(fixBG);
fixBG();
});
Explanation of the JavaScript code
The size of the background is determined by calculating the ratio of the background and document width. The width property is used, because it's the most reliable method for the calculation.
Then, the height of the viewport, document body and background is calculated. If applicable, the scrolling offset is also calculated, to prepare the movement of the background, if necessary.
Optionally, the code determines whether it's necessary to adjust the left margin (to keep the background visible at a narrow window).
Finally, if the background arrow has a greater height than the document's body, the background is moved accordingly, taking the scrolling position into account. The arrow starts at the top of the document, and will move up as the user scrolls (so that the bottom side of the arrow will be the bottom of the page when the user has fully scrolled down). If it's unnecessary to move the background, because it already suits well, the background will be positioned at the bottom of the page.
When the page has finished loading, this functionality is added to the Resize and scroll events, so that the background is always at the right location.
If you've got any other questions, feel free to ask them.
well, I'm not sure if I understand you and why do you want to do that, but you can try adding 2 backgrounds (see http://www.css3.info/preview/multiple-backgrounds/ ), one with the top bg and another with the bottom bg but I think that if the page is not too long it will cause issues, so the other answer with pure CSS is as follows: first add 3 horizontal divs with 100% width. Top div will have your top bg and its height, middle div will be transparent and auto height and bottom div will have your bottom bg and its height. All divs will have a 0 z-index. Then create a higher z-index div to act as a container and you'll be set. If I understand your question right, that's the close I can think of to achieve that. This being said, I'm pretty sure you can do this with JQuery with way better results
Using jQuery I was able to give you what I think you're asking for:
$(window).scroll(function() {
var h = Math.max($(document).height(), $(window).height());
var bottom = h - $(".background").height() - $(window).height();
$(".background").css("top", (($(window).scrollTop() / h) * bottom) + "px");
});
EDIT: Forgot to account for the way scrollTop reports position.
Or maybe:
.background {
margin-top: 45px;
max-width: 100%;
position: fixed;
bottom: 0;
left: 0;
z-index: -9999;
max-height: 100%;
}
I reccomend using jQuery Background Parallax
http://www.stevefenton.co.uk/Content/Jquery-Background-Parallax/
The function is as simple as
$("body").backgroundparallax();
Ask if you don't get it to work.
#abney; as i understand your question may that's you want http://jsfiddle.net/sandeep/RSqrw/60/
you need only css for this:
#background {
position: fixed;
width: 100%;
height:100%;
top: 0;
left:0;
z-index: -1;
}
The solution to your issue is a nice little lightweight plugin by Scott Robin. You can get more info, download it, and make your life easier for all of your projects by visiting his project page here.
Is there an html / css / javascipt way to maintain a <div> at a constant size in the face of the user's zooming the page in and out? That is, using control-plus to increase text size and control-minus to reduce it.
EDIT: The kicker, I guess, is that I want the content of the <div> to stay the same size, too.
Thanks!
EDIT: My goal was (and is) to keep an AdSense <div> from expanding so much as to obscure a lot of the real content on the page. But come to find out (thank you #thirtydot) there's really no good way to do this. The answer, for me (thank you #Neal!): give the <div> overflow:scroll so as to sacrifice its content rather than the content I'm trying to show.
.box {
background: red;
width: 5vw;
height: 10vh;
position: absolute;
top: 10vh;
left: 5vw;
}
<div class="box"></div>
There is no good way (read: reliable) to do this. Sorry.
What you're asking for basically boils down to detecting the zoom level of the browser, and there's a great answer here (confirming just how difficult this is):
How to detect page zoom level in all modern browsers?
As stated in that answer, there is a "kinda" cross-browser crazy way involving the use of Flash, but there are downsides:
It uses Flash.
It's not reliable if the user loads your page already zoomed in.
It uses Flash. Yes, this is so bad that I said it twice. Think of all those iPhones/iPads.
Anyway, it's here:
http://blog.sebastian-martens.de/2009/12/how-to-detect-the-browser-zoom-level-change-browser-zoo/
I am not sure what you mean, just use css:
div#id {
width: 100px; /*or some other #*/
height: 100px; /*or some other #*/
}
html:
<div id="id">some content</div>
To make the div size invariant of zooming (But not contents inside it) do the following :
Inside your css for that div :
min-width: 100%;
max-width: 100%;
This will freeze the width, you can do the same for height too.
You should just be ablemto set a width and height in css using a px measurement
Eg
div
{
width:100px; height:200px;
}
I read in another post a solution that I didn't test yet...
Maintain div size (relative to screen) despite browser zoom level
that's the used javascript:
//This floating div function will cause a div to float in the upper right corner of the screen at all times. However, it's not smooth, it will jump to the proper location once the scrolling on the iPhone is done. (On my Mac, it's pretty smooth in Safari.)
function flaotingDiv(){
//How much the screen has been zoomed.
var zoomLevel = ((screen.width)/(window.innerWidth));
//By what factor we must scale the div for it to look the same.
var inverseZoom = ((window.innerWidth)/(screen.width));
//The div whose size we want to remain constant.
var h = document.getElementById("fontSizeDiv");
//This ensures that the div stays at the top of the screen at all times. For some reason, the top value is affected by the zoom level of the Div. So we need to multiple the top value by the zoom level for it to adjust to the zoom.
h.style.top = (((window.pageYOffset) + 5) * zoomLevel).toString() + "px";
//This ensures that the window stays on the right side of the screen at all times. Once again, we multiply by the zoom level so that the div's padding scales up.
h.style.paddingLeft = ((((window.pageXOffset) + 5) * zoomLevel).toString()) + "px";
//Finally, we shrink the div on a scale of inverseZoom.
h.style.zoom = inverseZoom;
}
//We want the div to readjust every time there is a scroll event:
window.onscroll = flaotingDiv;