I have this markup:
<div class="container">
<figure></figure>
<figure></figure>
<figure></figure>
</div>
Now: I need to add for each of figures a symmetric element, but with different height and width value. For each item next I need to remove about 10% in width and height. So that the first has 90%, the second 80% and the third has 70% of initial size. I'm using the following code but it does not work, can anyone help?
var inside_element = $(figure);
var indx = 10;
inside_element.each(function(indx){
$(this).css({
width: '90%' - indx,
height: '90%' - indx
});
});
Thx.
You working on string '90%' and trying to complete math operation, which will fall. This should work:
var inside_element = $('figure');
var indx = 10;
inside_element.each(function(indx){
$(this).css({
width: (90 - (10*indx)) + '%' ,
height: (90 - (10*indx)) + '%'
});
});
Also declaration var indx = 10; is not necessary. This value will be overrided inside function.
EDIT: Also there can be more containers. Then code should look like this:
var inside_container = $('.inside_container');
inside_container.each( function(i) {
var inside_element = $(this).find('figure');
var step = 10;
inside_element.each(function(indx){
$(this).css({
width: (90 - (step*indx)) + '%' ,
height: (90 - (step*indx)) + '%'
});
});
});
You are calulating the next width and hight by substracting indx from a String.
try:
var width = 100;
var height = 100;
inside_element.each(function(indx){
width = width - 10;
height = height - 10;
$(this).css({
width: width + '%',
height: height + '%'
});
});
You are not selecting figure you need this $('figure');
var inside_element = $('figure');
inside_element.each(function(index){
$(this).css({
width: (90 - index * 10) +"%",
height:(90 - index * 10) +"%"
});
});
Try this:
var inside_element = $('figure');
var width = '90',
height = '90';
inside_element.each(function(indx){
$(this).css({
width: width + '%',
height: height + '%'
});
width = width - 10;
height = height - 10;
});
Related
I have ~33 divs that I am setting the position of randomly and animating this places. These divs are originally positioned with the help of flex and then the positions are randomized by setting their positions to relative and changing the left and top values. This happens every click.
On every alternate click, I want to return the divs to their normal position. So far the only solution to this I've found is the .removeAttr('style') method. However, I want to be able to animate their return to original position. Is this possible?
Here is the code:
var position_checker = false;
$(document).click(function() {
if(position_checker == false) {
$('.poster05-text').each(function() {
var position = $(this).offset();
$(this).css({
position: 'relative',
}, position);
var docHeight = $(document).height(),
docWidth = $(document).width(),
divWidth = 500,
divHeight = 500,
heightMax = docHeight - divHeight,
widthMax = docWidth - divWidth;
var posLeft = Math.floor(Math.random() * widthMax);
var posTop = Math.floor(Math.random() * heightMax);
// console.log(docHeight, docWidth);
$(this).animate({
position: 'fixed',
left: posLeft,
top: posTop
}, 1000 , 'easeInQuint');
});
position_checker=true;
}
else if(position_checker==true) {
$('.poster05-text').each(function() {
$(this).removeAttr('style');
});
position_checker=false;
}
});
I don't know this a right way to do that or not .. but anyway .. you need to save the previous left and top positions for each div on array
var position_checker = false , T_L_Positions = [];
$(document).click(function() {
if(position_checker == false) {
$('.poster05-text').each(function(i) {
var position = $(this).offset();
$(this).css({
position: 'relative',
}, position);
T_L_Positions[i] = new Array(position.top ,position.left);
var docHeight = $(document).height(),
docWidth = $(document).width(),
divWidth = 500,
divHeight = 500,
heightMax = docHeight - divHeight,
widthMax = docWidth - divWidth;
var posLeft = Math.floor(Math.random() * widthMax);
var posTop = Math.floor(Math.random() * heightMax);
// console.log(docHeight, docWidth);
$(this).animate({
position: 'fixed',
left: posLeft,
top: posTop
}, 1000 , 'easeInQuint');
});
position_checker=true;
}
else if(position_checker==true) {
$('.poster05-text').each(function(i) {
$(this).animate({
position: 'relative',
left: T_L_Positions[i][1],
top: T_L_Positions[i][0]
}, 1000 , 'easeInQuint');
});
position_checker=false;
}
});
Note: This Code Not Tested .. but you can try it
maybe you'll need to wrap your code in $(document).ready(function(){ //code here })
If you're looking for a non-JS solution. You should be able to use CSS Transitions to do this.
transition: top 500ms, left 300ms;
That way you can just set and remove the position and let CSS deal with the animation.
For more information check out these examples:
https://www.w3schools.com/css/css3_transitions.asp
https://css-tricks.com/almanac/properties/t/transition/
I'm trying to animate a div on scroll. The point is that the div's width must grow until it reaches 80vw and stop. This does happen, but my variable keeps on growing (it's being logged to the console) even if the >=outerWidth*0.8 condition isn't met. Thanks to this, whenever I get to 80vw and scroll up and then down, the width becomes Xvw.
$(window).on('scroll',function(){
var scrollTop = $(this).scrollTop();
var outerHeight = $(this).outerHeight();
var outerWidth = $(this).outerWidth();
var scrollBottom = scrollTop + outerHeight;
var scrollTop = $(this).scrollTop();
console.log( growNaranja );
if (scrollTop > lastScrollTop){ // scroll down
if( naranjaWidth <= (outerWidth*0.8) ){
growNaranja = (naranja.outerWidth()*100) / outerWidth;
growNaranja = growNaranja+(scrollTop*0.05);
$('.grow.naranja').css( 'width', growNaranja + 'vw' );
}
} else { // scroll up
if( naranjaWidth >= (outerWidth*0.1) ){
growNaranja = (naranja.outerWidth()*100) / outerWidth;
$('.grow.naranja').css( 'width', growNaranja + 'vw' );
growNaranja = growNaranja - ((lastScrollTop-scrollTop)*0.05);
$('.grow.naranja').css( 'width', growNaranja + 'vw' );
}
}
lastScrollTop = scrollTop;
});
You can see a working example here.
Revisited this one, it was bugging me. First, the code was all spaghetti. Second, there was really function duplication. You had a function for scrolling up and one for scrolling down, and you were using the last scrollTop to calculate the next scroll step. Instead, I've made a single scale function that gets called regardless. The value of the percentage scrolled is multiplied by the step factor, and that is added to the ORIGINAL element width. By doing this, I'm not worried about where I was just prior to the scroll, only where I am now.
So I made the scaleWidthEl an object constructor, and simply wrapped the naranja div in that. The actual code to create it is the first three lines, and could be reduced to:
var scaleNaranja = new ScaleWidthEl($('.grow.naranja'), 0.8);
The rest is self-contained, allowing changes to be made without affecting anything else.
var maxElScale = 0.8;
var naranja = $('.grow.naranja');
var scaleNaranja = new ScaleWidthEl(naranja, maxElScale);
/***
* The rest of this is a black-box function, walled away from the main code
* It's a personal peeve of mine that code gets garbled otherwise.
***/
function ScaleWidthEl(el, maxScale) {
// I don't need a minScale, as I use the initial width for that
this.el = el;
this.vwConversion = (100 / document.documentElement.clientWidth);
this.startingWidth = el.outerWidth();
this.maxScale = maxScale;
this.max = $(window).outerWidth() * this.maxScale;
this.step = (this.max - this.startingWidth) / $(window).outerHeight();
// for the sake of clarity, store a reference to `this` for
// any nested functions.
var that = this;
/**
* function scaleEl
* handle the actual scaling of the element.
* Using a given step, we will simply add that
* to the element's current width, then update the CSS
* width property of the element.
**/
this.scaleEl = function() {
// First, calculate the percentage of vertical scroll
var winheight = $(window).height();
var docheight = $(document).height();
var scrollTop = $(window).scrollTop();
var trackLength = docheight - winheight;
// gets percentage scrolled (ie: 80 NaN if tracklength == 0)
var pctScrolled = Math.floor(scrollTop / trackLength * 100);
// console.log(pctScrolled + '% scrolled')
// Now, using the scrolled percentage, scale the div
var tempWidth = this.startingWidth * this.vwConversion;
tempWidth += pctScrolled * this.step;
// I want to fix the max of the scale
if (tempWidth > (this.maxScale * 100)) {
tempWidth = this.maxScale * 100;
}
this.el.css('width', tempWidth + 'vw');
};
$(window).on("scroll", function() {
that.scaleEl();
}).on("resize", function() {
/**
* In the case of a resize, we should
* recalculate min, max and step.
**/
that.min = $(window).outerWidth() * that.minScale;
that.max = $(window).outerWidth() * that.maxScale;
that.step = (that.max - that.min) / $(window).outerHeight();
})
}
body {
height: 10000px;
}
.grow {
position: fixed;
height: 100vh;
top: 0;
left: 0;
}
.grow.gris {
width: 35vw;
z-index: 2;
background: silver;
}
.grow.naranja {
width: 10vw;
z-index: 1;
background: orange;
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js" crossorigin="anonymous"></script>
<div class="grow naranja"></div>
<!-- .naranja -->
I have a wrapper called #mousearea and I have a div called #mouseshift what I would like to do is when I hover over #mousearea I would like to shift the translate3d(0,230%,0) value between a particular range.
I have got the mousemove working but I currently end up with something like translate3d(7881%,230%,0) it's just too sensetive I would like it to translate the X co-ordinate between something like 0-60% so it's far more subtle.
Here is what I have so far:
jQuery(document).ready(function($){
$('#mousearea').mousemove(function (e) {
var shiftAmount = 1;
$('#mouseshift').css(
'transform', 'rotate(90deg) translate3d(' + -e.pageY + shiftAmount + '%,230%,0)'
);
});
});
Update:
This is a little closer, except it logs the correct translate3d but doesn't apply it to #mouseshift.
$('#mousearea').mousemove(function(e){
var x = e.pageY - this.offsetTop;
var transfromPosition = 'translate3d(' + x + ', 230%, 0)';
console.log(transfromPosition);
if ((x <= 800)) {
//$('#mouseshift').css({'top': x});
$('#mouseshift').css('transform', transfromPosition);
}
});
Final Solution:
jQuery(document).ready(function($){
$('#mousearea').mousemove(function(e){
var min = 50;
var max = 70;
var x = e.pageY;
var windowHeight = window.innerHeight;
scrolled = (x / windowHeight);
percentageScrolled = scrolled * 100;
offsetScroll = max - min;
offsetPercentage = scrolled * 20;
translateX = min + offsetPercentage;
console.log(x + 'px');
console.log(windowHeight + 'px window height');
console.log(percentageScrolled + '% scrolled');
console.log(offsetScroll + 'offset scroll');
console.log(offsetPercentage + '% offset percentage');
var transfromPosition = 'rotate(90deg) translate3d(' + translateX + '%, 230%, 0)';
$('#mouseshift h1').css('transform', transfromPosition);
});
});
Convert to a reusable plugin I would like to extend this to work with more than one object now and each object would have a different max and min value:
This is what I have but it seems to effect all the items on only use on elements max and min.
$(function () {
$('#mouseshift-1, #mouseshift-2').mouseShift();
});
(function ($) {
$.fn.mouseShift = function () {
return this.each(function () {
var myEl = $(this);
var min = $(this).data('min');
var max = $(this).data('max');
$('#mousearea').mousemove(function (e) {
var yPosition = e.pageY;
var windowHeight = window.innerHeight;
scrolled = (yPosition / windowHeight);
//percentageScrolled = scrolled * 100;
offsetRange = max - min;
offsetRangePercentage = scrolled * 20;
offset = min + offsetRangePercentage;
//// Debug
console.log('max: ' + max + ', Min:' + min);
console.log(yPosition + 'px');
console.log(windowHeight + 'px window height');
//console.log(percentageScrolled + '% scrolled');
console.log(offsetRange + 'px offset scroll');
console.log(offsetRangePercentage + '% offset percentage');
var transfromPosition = 'rotate(90deg) translate3d(' + offset + '%, 230%, 0)';
myEl.css('transform', transfromPosition);
});
});
};
})(jQuery);
And some HTML for clarity:
<div class="column"><h1 id="mouseshift-1" data-min="50" data-max="70">boo</h1></div>
<div class="column"><h1 id="mouseshift-2" data-min="20" data-max="90">bah</h1></div>
<div class="column"><h1 id="mouseshift-3" data-min="80" data-max="100">bing</h1></div>
I think what you are looking for is finding an average that your can distribute. The best way to do this is to divide by the maximum amount it can move, and multiply it by the maximum value it can have, so basically:
position / maxposition * maxvalue
The first bit will return a number between 0 and 1, while the last bit will make it the value between 0 and 60. Below I have built a simply (jquery-less) version of it to show how this would work:
var mousePointer = document.getElementById('test')
document.addEventListener('mousemove', function(e){
var x = e.pageX / window.innerHeight;
x = x * -60;
mousePointer.style.webkitTransform = 'translateX(' + x + '%)';
mousePointer.style.transform = 'translateX(' + x + '%)';
})
#test {
position: absolute;
left: 50%;
top: 50%;
width: 20px;
height: 20px;
background: red;
}
<div id="test"></div>
Update: Reusable Snippet
I don't really like using jQuery, so once again it will be vanilla javascript (but it's pretty simple). Is that what you were - sort of - trying to do with the reusable plugin?
var divs = Array.prototype.slice.call(document.querySelectorAll('[data-range]'));
document.addEventListener('mousemove', function(e){
var eased = e.pageX / window.innerWidth;
divs.forEach(function(div){
var range = div.getAttribute('data-range').split(',');
var min = parseFloat(range[0]);
var max = parseFloat(range[1]);
var ease = min + (eased * (max - min));
div.style.webkitTransform = 'translateX(' + ease + '%)';
div.style.transform = 'translateX(' + ease + '%)';
});
});
div {
position: absolute;
left: 50%;
top: 50%;
width: 200px;
height: 200px;
background: gray;
}
#d2 { background: yellow; }
#d3 { background: #666; }
<div data-range="60,70" id="d1"></div>
<div data-range="-70,70" id="d2"></div>
<div data-range="-60,-70" id="d3"></div>
From simple reading, I see that you're missing a % sign. Should be like this:
$('#mousearea').mousemove(function(e){
var x = e.pageY - this.offsetTop;
var transfromPosition = 'translate3d(' + x + '%, 230%, 0)';
console.log(transfromPosition);
if ((x <= 800)) {
//$('#mouseshift').css({'top': x});
$('#mouseshift').css('transform', transfromPosition);
}
});
This should be working like your first example, where you do use % for both values inside the translate3d string.
Update:
To coerce your x Value to something between 0 and 60, you need to find a pair of possible min and max values for x. Then you can do something like what's shown in this answer:
Convert a number range to another range, maintaining ratio
I have an animations with jQuery which looks like that:
$(function() {
var elems = $('div.icon').not('#icon-0');
var increase = Math.PI * 2 / elems.length,
x = 0,
y = 0,
angle = 0,
radius = 200;
var center_top = ($("#slider-1").outerHeight() - $("#icon-0").outerHeight())/2,
center_left = ($("#slider-1").outerWidth() - $("#icon-0").outerWidth())/2;
$('.icon').css({
'top': center_top + 'px',
'left': center_left + 'px'
});
$(elems).css('opacity', '0').each(function(i) {
elem = elems[i];
x = radius * Math.cos(angle) + center_left;
y = radius * Math.sin(angle) + center_top;
$(elem).delay(400*i).animate({
'position': 'absolute',
'left': x + 'px',
'top': y + 'px',
'opacity': '1'
}, 1000);
angle += increase;
});
});
http://jsfiddle.net/d6pYR/
How do I write the line between the circle in the center and each of the outer circles?
I tried with the canvas and getting center coordinates via offset and some easy math, but canvas wouldn't do it properly or I just can't do that.
I'd appreciate any help from you guys.
Cheers!
taking into mind that you do not want to use canvas (or is not feasible) made a solution using css3 transform ...
follows the solution
in this JSFiddle -> http://jsfiddle.net/d6pYR/2/
you need to create more one css class to make a line
.line {
border-top: 1px solid black;
position: absolute;
height: 1px;
opacity: 0;
-webkit-transform-origin: left;
transform-origin: left;
}
to create a element you can create in loop
var line = $("<div class='line'></div>");
slider.append(line);
line.css("width", 0);
line.css("top", center_top + ( $(this).height() / 2 ) );
line.css("left", center_left + ( $(this).width() / 2 ) );
line.css("transform", "rotateZ(" + angle + "rad)");
I have a div tag with id container. How can I find its center using either jquery or javascript?
<div id="container"></div>
here is css
#container {
width: 300px;
height: 300px;
border: 1px solid red;
}
Is it this?
var cX = $('#container').offset().left + $('#container').width()/2;
var cY = $('#container').offset().top + $('#container').height()/2;
$(function(){
var $this = $("#container");
var offset = $this.offset();
var width = $this.width();
var height = $this.height();
var centerX = offset.left + width / 2;
var centerY = offset.top + height / 2;
console.log(centerX ,centerY)
})
You should check:
width / outerWidth
height / outerHeight
jQuery way:
var div = $('#container');
var divCoords = {
x : div.width() * 0.5 ,
y : div.height() * 0.5
};