Using the code submitted here, how could I do a similar (if not the same) thing within the confines of a predefined div?
The code 2pha provided has variables for the width and height of where to render these objects, but I'm not sure how to actually position the "box" within which it is rendering them.
It is probably worth noting that I am an extreme beginner, so please forgive me if this is a stupid question.
Thanks a lot :)
In the code you're looking at the width and height of the entire window are determined, and used as bounds for all the random boxes:
var ww = $(window).width();
var wh = $(window).height();
If, instead, you want all your random boxes inside another div (I've given it the id container) you could just read the width and height of that box.
var ww = $("#container").width();
var wh = $("#container").height();
You would also want to append the random boxes to your container div, rather
than the body.
for(var x=1;x<=numTickets;x++){
$(ticket).appendTo("#container");
}
Here's a demo:
var ticket="<div class='ticket'><p>Random<br />Box</p></div>";
var numTickets=10;
for(var x=1;x<=numTickets;x++){
$(ticket).appendTo("#container");
}
// get container dimentions
var ww = $("#container").width();
var wh = $("#container").height();
$(".ticket").each(function(i){
var rotationNum=Math.round((Math.random()*360)+1);
var rotation="rotate("+rotationNum+"deg)";
var posx = Math.round(Math.random() * ww)-20;
var posy = Math.round(Math.random() * wh)-20;
$(this).css("top", posy + "px").css("left", posx + "px").css("transform",rotation).css("-ms-transform",rotation).css("-webkit-transform",rotation);
});
.ticket{
position: absolute;
background: #F90;
padding: 7px 3px;
}
#container{
width:400px;
height:400px;
border:1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
Related
I've tried to find similar posts about this but failed to do so. What I'm trying to do is set up a parallax background that has a moderate zoom upon scrolling. I have the parallax down, that was simple enough, but the zoom on scroll is causing me difficulties.
if ($(".zoomImage").length == 0)
{
console.warn("You're attempting to set hero images without an existing class. '.heroImage'");
return;
}
$(document).scroll(function(){
var scrollpos = $(this).scrollTop();
var screenHeight = $(window).height();
var screenWidth = $(window).width();
$(".zoomImage").each(function(){
var offset = $(this).offset().top;
// Only modify when top is at top of browser on screen.
if (offset < scrollpos && scrollpos < offset + screenHeight)
{
var heroEffectPerc = 100 + 25 * (scrollpos - offset) / (screenHeight * 1.0);
$(this).css("background-size", heroEffectPerc + "% auto");
}
});
});
This is where I'm doing the zoom for the image, the parallax is done in pure CSS as represented below. The issue I'm having is figuring out the mathematics to make sure that the image doesn't escape the edge of its parent when the screen gets excessively wide or tall and still achieve the same effect. 1:
CSS:
pageCanvas
{
position: relative;
background-repeat: no-repeat;
background-position: center;
background-size: auto 100%;
background-color: white;
display: block;
left: 0;
top: 0;
width: 100%;
height: 100vh;
}
pageCanvas.parallax
{
background-attachment: fixed;
}
.
<pageCanvas class="parallax zoomImage" style="background-image: url('./Images/DisplayBackground.png');">
<banner>
<header>
Company name
</header>
<description>
I don't want to<br><span style="margin-left: 200px;">advertise here.</span>
</description>
</banner>
</pageCanvas>
I've tried to get it working, but either have an issue with one of the following:
White background shows on too wide.
White background shows on too tall.
Image stretching.
Do I need to bring in the images origin ratio with this or something? If I figure out a solution prior to an answer given, I'll post it.
Although the original was in a namespace, I'm going to place this answer as if it were not because I hadn't specified. Either way, I found the solution.
The first step was finding the ratio of the original image;
$(".zoomImage").each(function(index){
var bg = $(this).css('background-image');
bg = bg.replace('url(','').replace(')','').replace(/\"/gi, "");
// get image size.
var tmpImg = new Image();
tmpImg.src=bg;
$(tmpImg).one('load', function(){
orgWidth = tmpImg.width;
orgHeight = tmpImg.height;
bgImageRatios[index] = orgHeight / (orgWidth * 1.0);
});
});
To make life easier, I placed them in an array that was global to the name space. This is so I don't have to A) keep finding the ratio of the image, and B) can access it similarly to initializing later on. It should be noted that this method would require being called again in the instance there is any more or less '.zoomImage' classes brought into instance, as the array will be incorrect at that point.
What I did next was place the original code that loops the class into a function.
function zoomImage(scrollpos, screenHeight, screenWidth)
{
//console.log(screenHeight);
$(".zoomImage").each(function(index){
var offset = $(this).offset().top;
if (offset < scrollpos && scrollpos < offset + screenHeight)
{
var heroEffectPerc = 100 + 25 * (scrollpos - offset) / (screenHeight * 1.0);
if ((bgImageRatios[index] * screenWidth / screenHeight) > 1)
$(this).css("background-size", heroEffectPerc + "% auto");
else
$(this).css("background-size", "auto " + heroEffectPerc + "%");
}
});
}
I put it into a function because it would have been placed into two separate locations otherwise. (that's just messy coding). I updated the image size as follows.
$(window).on("resize", function(){
var scrollpos = $(document).scrollTop();
var screenHeight = $(this).height();
var screenWidth = $(this).width();
pageCanvas.zoomImage(scrollpos, screenHeight, screenWidth);
});
$(document).on("scroll", function(){
var scrollpos = $(this).scrollTop();
var screenHeight = $(window).height();
var screenWidth = $(window).width();
pageCanvas.zoomImage(scrollpos, screenHeight, screenWidth);
});
The following sources helped me solve my answer:
Can I get div's background-image url?
How to get image size from URL
Credit is due to them.
Banging my head trying to sort out the correct logic for adding simple parallax behavior.
I would like to have a number of elements on a page which start out with their top offset a certain distance (e.g. 300px). Then as you scroll down the page, once the top of the element is revealed it will slowly shift upwards (tied to scroll) until the top of element reaches middle of viewport at which time it's top offset is 0 and it remains in place.
I tried using third party script (Scroll Magic, Stellar, etc), but when I couldn't get it right now I'm trying custom code:
https://jsfiddle.net/louiswalch/5bxz8fku/1/
var $Window = $(window);
var offset_amount = 400;
var window_height = $Window.height();
var window_half = (window_height/2);
var sections = $('SECTION.reveal');
sections.each(function() {
var element = $(this);
// Make sure we always start with the right offset
element.css({top: offset_amount});
$Window.bind('scroll', function() {
var viewport_top = $Window.scrollTop();
var viewport_middle = viewport_top + (window_height/2)
var viewport_bottom = viewport_top + window_height;
var element_top = element.offset().top;
if (element_top > viewport_top && element_top <= viewport_bottom) {
var distance_to_middle = (element_top - viewport_middle);
var amount_to_middle = (distance_to_middle / window_half);
console.log(amount_to_middle);
if (amount_to_middle >= 0) {
element.css({top: (offset_amount * amount_to_middle)+ 'px'});
} else {
// ? Lock to end position ?
}
}
});
});
jsBin demo 1. (margin space effect on both enter and exit)
jsBin demo 2. (preserve 0 margin once touched)
Instead of targeting the section elements, (create and) target their first child elements,
otherwise you'll create a concurrency mess trying to get the top position but simultaneously modifying it.
Also, you cannot rely on fixed 300px margin (i.e: if window height is less than 500px, you're already missing 100px). That space can vary when the screen height is really small, so you also need to find the idealMarg value.
var $win = $(window),
$rev = $('.reveal'),
winH2 = 0,
winSt = 0;
function reveal() {
winSt = $win.scrollTop();
winH2 = $win.height()/2;
$rev.each(function(i, el){
var y = el.getBoundingClientRect().top,
toMiddleMax = Math.max(0, y-winH2),
idealMarg = Math.min(300, toMiddleMax),
margMin = Math.min(idealMarg, idealMarg * (toMiddleMax/winH2));
$(">div", this).css({transform: "translateY("+ margMin +"px)"});
});
}
$win.on({"load resize scroll" : reveal});
*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0;}
section > div{
padding: 40px;
min-height: 100vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div style="background-color:red">1</div>
</section>
<section class="reveal">
<div style="background-color: yellow">2</div>
</section>
<section class="reveal">
<div style="background-color: orange">3</div>
</section>
<section class="reveal">
<div style="background-color: pink">4</div>
</section>
I've used in HTML just a <div> logically, that has to be the one and only first child of a section parent.
You're welcome to tweak the above code to make it more performant.
Hey so here is my go at an awnser.
http://jsbin.com/wibiferili/edit?html,js,output
The jist of it is as follows.
JS
var $Window = $(window),
parallaxFactor = 2;
$('.parallaxblock').each(function(a,b){
var element = $(b);
element.css("top",element.data("pOffset") + "px");
$Window.bind('scroll', function() {
var pos =
// Base Offset
element.data("pOffset")
// parallaxFactor
- ($Window.scrollTop() / parallaxFactor);
pos = pos < 0 ? 0 : pos;
element.animate({"top": pos + "px"},10);
return;
});
});
Styles
body{
height: 4000px;
}
.parallaxblock{
position:fixed;
background:#999;
opacity:.5;
}
Example Usage
<div class="parallaxblock" data-p-offset=100>Im A Block</div>
<div class="parallaxblock" data-p-offset=200>Im Also Block</div>
<div class="parallaxblock" data-p-offset=1500>Im Another Block</div>
So by checking the offest its never lower then 0 we can lock it at the top of the screen once it reaches it.
I get the offset amount of the data tag on the div.
If you wanted to change the rate of scroll in different posistions you could change the parallax factor at a certain percentage of screen height.
Hope this helps.
So I've got the site JobCreatr.com. It is based on Drupal.
I am trying everything I can to get a sticky footer working and it just isn't working.
Currently I'm using the following jQuery to do it:
(function ($) {
$(function(){
positionFooter();
function positionFooter(){
var padding_top = $("#footer-wrapper").css("padding-top").replace("px", "");
var page_height = $(document.body).height() - padding_top;
var window_height = $(window).height();
var difference = window_height - page_height;
if (difference < 0)
difference = 0;
$("#footer-wrapper").css({
padding: difference + "px 0 0 0"
})
}
$(window)
.resize(positionFooter)
});
})(jQuery);
Which as far as I can tell, should dynamically adjust footer size.
I've also tried absolute positioning, etc with CSS.
I'm at a loss at why it isn't working. I just want to have a uniform height footer on all pages, with no white space underneath.
Try this:
Add this on you #footer-wrapper position: absolute; bottom: 0; width: 100%; border: 0px;`
I see width: 80%; on .container remove that.
See this preview and edited it thorugh Chrome Dev Tools:
Try, something more like:
(function($){
function positionFooter(){
var padding_top = $('#footer-wrapper').css('padding-top').replace('px', '');
var page_height = $(document.body).height() - padding_top;
var window_height = $(window).height();
var difference = window_height - page_height;
if(difference < 0)difference = 0;
$('#footer-wrapper').css({padding: difference+'px 0 0 0'});
}
positionFooter();
$(window).resize(positionFooter);
})(jQuery);
Remember that a line break in JavaScript is similar to ;. Where I put the positionFooter() function doesn't make a difference.
I am developing a bunch of small web applications that have an unknown window size as target. To solve this problem, I am developing very large layouts and scaling them according to the window size.
My solution however has an inconvenience. When I resize everything, things get a little bit out of place (mainly when scaling text) and it is noticeable. My code is very simple, everything in my page is absolutely positioned so I just get the scaling factor and apply it to all the positions and width / height of every div/img/span/input in the page. The code is as follows:
function resize()
{
var wh = $(window).height();
var h = maxHeight;
var ww = $(window).width();
var w = maxWidth;
var wProp = ww / w;
var hProp = wh / h;
if (wProp < hProp) prop = wProp;
else prop = hProp;
if (prop > 1) prop = 1;
console.log(prop);
$("div").each (applyNewSize);
$("img").each (applyNewSize);
$("span").each (applyNewSize);
$("input").each (applyNewSize);
}
//this is run when the page is loaded
function initializeSize (i)
{
this.oX = $(this).position().left;
this.oY = $(this).position().top;
this.oW = $(this).width();
this.oH = $(this).height();
if ($(this).css("font-size") != undefined)
{
this.oFS = Number($(this).css("font-size").split("px")[0]);
}
}
function applyNewSize (i)
{
if (this.oFS != undefined) $(this).css("font-size", Math.round(this.oFS * prop) + "px");
$(this).css("left", Math.round(this.oX * prop) + "px");
$(this).css("top", Math.round(this.oY * prop) + "px");
$(this).width(Math.round(this.oW * prop));
$(this).height(Math.round(this.oH * prop));
}
This problem has been tormenting me for the past week. Do you have any workaround or solution for this?
I recommend you to read about Responsive Web design.
It works putting % instead the exact pixels :
<div class="container">
<section>
THIS IS THE SECTION
</section>
</div>
CSS::
.container{
width: 80%; // 80% instead pixels
background: gainsboro;
border: 3px inset darkgrey;
height: 200px;
margin:auto;
text-align:center;
}
section{
width: 80%; // 80% instead pixels
height: 80%; // 80% instead pixels
background: darkgrey;
margin:auto;
}
Then you can use media queries as well, to reallocate the blocks or applying different styles on different widths :
example tutorial : http://css-tricks.com/css-media-queries/
This is a bit annoying: i have a div which starts its transition from the top left of the window even when positioned anywhere else on the document. I've tried usign -webkit-transform-origin with no success, maybe i've used it wrong.
Could anybody help me? :)
Here's the code... all of it, but i've commented on the relevant parts - which are at the bottom, mainly.
Here's a live version of the code.
<style>
#pool{
width:100%;
}
.clickable{
<!-- class of the element being transitioned -->
display:inline;
margin-right: 5px;
-webkit-transition: all 500ms ease;
position: absolute;
}
.profile_image{
border: solid 1px black;
-webkit-transition: all 500ms ease;
position:relative;
}
</style>
<section id="pool"></section>
<script>
var Cache = {};
Cache.hasItem = function(item_key){
if(!localStorage.getItem(item_key)){
return false;
}else{
return true;
}
}
Cache.storeItem = function(key, value){
localStorage.setItem(key, value);
}
Cache.fetch = function(key){
return jQuery.parseJSON(localStorage.getItem(key));
}
Cache.clear = function(key){
localStorage.removeItem(key);
}
var Twitter = {};
Twitter.url = "http://api.twitter.com/1/statuses/public_timeline.json?callback=?";
Twitter.getFeed = function(){
console.log("Fetching...");
$.getJSON(Twitter.url, function(json){
Cache.storeItem('feed',JSON.stringify(json));
})
.complete(function(){
//to be implemented
console.log("Completed");
})
}
if(!Cache.hasItem('feed')){
Twitter.getFeed();
}
var feed = Cache.fetch('feed');
for(var i in feed){
var entry = feed[i];
var element = '<div id="'+i+'" class="clickable"><img class="profile_image" src="'+entry.user.profile_image_url+'"/></div>';
$("#pool").append(element);
}
</script>
<script>
$(".profile_image").click(function(e){
var target = $(e.target);
var parent = target.parent();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
var newWidth = 500;
var newHeight = 100;
var newX = (windowWidth-newWidth)/2;
var newY = (windowHeight-newHeight)/3;
/************HERE'S THE PROBLEM*******/
parent.css('background-color','red');
parent.css('display','inline');
parent.css('position','fixed'); // tried absolute and inherit as well
parent.css('z-index','3');
parent.width(newWidth).height(newHeight).offset({top:newY, left:newX});
})
</script>
Results:
With help from jfriend00 i managed to fix it. Here's the code:
<style>
#pool{
width:100%;
display: inline;
}
.clickable{
display: inline-block;
margin-right: 5px;
position: scroll;
}
.profile_image{
border: solid 1px black;
}
</style>
And the Javascript:
<script>
$(".profile_image").click(function(e){
var target = $(e.target);
var parent = target.parent();
targetOffset = target.offset();
parentOffset = parent.offset();
target.css('top',targetOffset.top-5);
target.css('left',targetOffset.left-5);
parent.css('top',parentOffset.top);
parent.css('left',parentOffset.left);
var windowWidth = $(window).width();
var windowHeight = $(window).height();
var newWidth = 500;
var newHeight = 100;
var newX = (windowWidth-newWidth)/2;
var newY = (windowHeight-newHeight)/3;
parent.css('-webkit-transition', 'all 500ms ease');
parent.css('background-color','red');
parent.css('position','absolute');
parent.css('z-index','3');
parent.width(newWidth).height(newHeight).offset({top:newY, left:newX});
})
</script>
It looks to me like you change the object's position from relative to fixed upon the click (along with a few other style changes). When you change it to fixed, the object is no longer positioned in the flow of the page and it goes to it's left and top position on the page which it does not look like you've initialized - thus they are set to (0,0) so that's where the object jumps to when you change it's position to fixed (top/left of the page).
If you want them to transition from where they were, you will have to calculate their original position on the page and set top and left to those values in the same code where you set the position to fixed.
I would assume that jQuery has a function to calculate the object's absolute position in the page for you so you can use that (YUI has such a function so I assume jQuery probably does too). Since you're using "fixed", you may have to correct that for scroll position or use "absolute" instead of "fixed". One challenge here is you need to change the position and top/left without them being subject to a CSS transition because you want those attributes to change immediately. Then, you enable the transitions and set the final position.