Here is a Simple truth.
Here is a guy at Change variable values on window.resize who has solved the Window resize update problem.
var windowHeight = $(window).height();
$(window).resize(function(){
windowHeight = $(window).height(); // get new height after change
});
However it does not work when i try to It in this manner by doing:
radius = Math.round( (($(window).width()) * 0.1302) / Math.tan( Math.PI / itemLength ) );
$(window).resize(function(){
radius = Math.round( (($(window).width()) * 0.1302) / Math.tan( Math.PI / itemLength ) );
});
The calculation works as it is supposed to but it never refreshes the calculation on resize.
can you help me figure out why that is ?
I think that this whole part of the code that is in your init() function :
// set container 3d props
TweenMax.set(container, {perspective:600})
TweenMax.set(carousel, {z:-(radius)})
// create carousel item props
for ( var i = 0; i < itemLength; i++ )
{
var $item = item.eq(i);
var $block = $item.find('.carouselItemInner');
TweenMax.set($item, {rotationY:rY * i, z:radius, transformOrigin:"50% 50% " + -radius + "px"});
}
must also be in the $(window).resize function. Else it won't update the items and the carousel, it will only update the variable radius.
The Solution turned out to involve more than I had expected. It was a line by Mario Werner that finally led me to the solution. After hours of flaming and indications that I was stupidity itself. Mario finaly gave the clue I needed. He said; "Outside the function's scope the radius variable is not available and thus will not be changed by this event."
This made me realize the problem and went on to do this:
$(window).resize(function(){
$(document).ready( init )
function init()
{
w = $(window);
container = $( '#contentContainer' );
carousel = $( '#carouselContainer' );
item = $( '.carouselItem' );
itemLength = $( '.carouselItem' ).length;
fps = $('#fps');
rY = 360 / itemLength;
radius = Math.round( (($(window).width()) * 0.1302) / Math.tan( Math.PI / itemLength ) );
// set container 3d props
TweenMax.set(container, {perspective:600})
TweenMax.set(carousel, {z:-(radius)})
// create carousel item props
for ( var i = 0; i < itemLength; i++ )
{
var $item = item.eq(i);
var $block = $item.find('.carouselItemInner');
TweenMax.set($item, {rotationY:rY * i, z:radius, transformOrigin:"50% 50% " + -radius + "px"});
animateIn( $item, $block )
}
// set mouse x and y props and looper ticker
window.addEventListener( "mousemove", onMouseMove, false );
ticker = setInterval( looper, 1000/60 );
}
});
I simply placed the resize event outside the init function and copy pasted the exact same init function inside resize event. This works!
Thank you Mario!
Related
Im still new to this type of programming, im trying to create kaledoscope kind of effect to be projected on screen. I want to make the image move isnide each section of the effect. is there a way to move it? i cant seem to target the canvas created by the plug in.
https://codepen.io/muspelheim/pen/gpymF
var images = [
"http://media-cache-ak0.pinimg.com/736x/5d/d8/41/5dd8416cbae27edeac61aa525a5df99d.jpg",
"https://1.bp.blogspot.com/-FpxaoVBBxXs/T5aWaP2dMDI/AAAAAAAAAw8/qdaPYyuqSt8/s1600/spugnaepicinfame.jpg",
"https://25.media.tumblr.com/tumblr_m9ls7nRTuR1rvqbato1_1280.jpg",
"https://3.bp.blogspot.com/-SJAKrZTcqwI/T5kwYk71YCI/AAAAAAAAAxE/HNlX3i2-xwk/s1600/spugnabimbofango.jpg"
];
// Let's create graphemescope object inside the container
var container = $("#container");
var scope = new Graphemescope( container[0] );
var index = 0;
function changePicture() {
scope.setImage(images[index]);
index = (index + 1) % images.length;
};
setInterval(changePicture, 2000);
changePicture();
$(window).mousemove(function(event) {
var factorx = event.pageX / $(window).width();
var factory = event.pageY / $(window).height()
// This will move kaleidoscope
scope.angleTarget = factorx;
scope.zoomTarget = 1.0 + 0.5 * factory;
});
var resizeHandler = function() {
container.height( $(window).height() );
container.width( $(window).width() );
};
$(window).resize(resizeHandler);
$(window).resize();
container.click(changePicture);
I'm trying to make a random slideshow of images for a gallery. I have two images on the page – the "front" one and the "back" one, and I have a timer set up to, every few seconds, move the back image to the front and load a new back image. I'm basically doing this by swapping the image objects in the code.
As the back image becomes the front image, I have it fade in gradually from an opacity of 0 to an opacity of 1, while I have the front image do the same in reverse. I implemented this as follows:
var fadeOutCt = 0;
var fadeOutInterval;
// Decrements the opacity of element by amt, until cap
function decrementOpacity( element, amt, cap ) {
var currentOpacity = Number( window.getComputedStyle( element ).getPropertyValue( "opacity" ) );
currentOpacity = currentOpacity - amt;
element.setAttribute( "style", "opacity:" + currentOpacity );
fadeOutCt = fadeOutCt + 1;
if ( fadeOutCt >= cap ) {
element.setAttribute( "style", "opacity:0" );
clearInterval( fadeOutInterval );
}
}
// Calls decrementOpacity to fill the specified interval.
function fadeOut( element, interval ) {
var currentOpacity = Number( window.getComputedStyle( element ).getPropertyValue( "opacity" ) );
fadeOutCt = 0;
if ( currentOpacity > 0 ) {
cap = interval / 10.0;
amt = 1.0 / cap;
fadeOutInterval = setInterval( decrementOpacity, 10, element, amt, cap );
}
}
Separately, I have another routine that resizes the image I load to conform to the user's screen (it also centers the image). I run this immediately before the fade-in or fade-out operation.
function resizeForSlideshow( imgToResize ) {
// Get size of usable area for slideshow
var usableWidth = window.innerWidth;
var titleTable = document.getElementById( "descTable" );
var windowHeight = window.innerHeight;
var tableHeight = titleTable.offsetHeight;
var usableHeight = windowHeight - tableHeight;
// Resize containing div
var slideDiv = document.getElementById( "slideDiv" );
slideDiv.setAttribute( "style", "height:" + usableHeight + "px" );
// Get size of native image to be displayed
var nativeWidth = imgToResize.naturalWidth;
var nativeHeight = imgToResize.naturalHeight;
// Determine width-to-height ratios of those two
var windowRatio = usableWidth / usableHeight;
var imageRatio = nativeWidth / nativeHeight;
if ( imageRatio > windowRatio ) {
// image's width-to-height is greater than window
// image should be set to 100% width, less height
imgToResize.width = usableWidth;
imgToResize.height = usableWidth * ( nativeHeight / nativeWidth );
// relocate image accordingly
var newTop = ( usableHeight - imgToResize.height ) / 2;
imgToResize.style.left = 0;
imgToResize.style.top = newTop + "px";
}
else {
// image's width-to-height is less than window
// image should be set to 100% height, less width
imgToResize.height = usableHeight;
imgToResize.width = usableHeight * ( nativeWidth / nativeHeight );
// relocate image accordingly
var newLeft = ( usableWidth - imgToResize.width ) / 2;
imgToResize.style.top = 0;
imgToResize.style.left = newLeft + "px";
}
}
The problem is, when I fade in or fade out, it breaks the positioning of my images. Instead of being centered, they revert to being on the top left of the page (though their size remains what it should be). I've tried a few things but I'm out of ideas, and I was hoping someone would be able to shed some light on what's going wrong here and how I could fix it.
(If seeing the code in action would help: http://artmonitors.com/slideshow/full-slideshow.html
EDIT: I later figured out the problem.
The problem is that using setAttribute to set opacity also removed the positional settings I had given. Manually setting element.style.opacity made things work.
How about centering it with css?
.slide {
display: block;
margin: auto;
position: relative;
}
You should close the style with ;
element.setAttribute( "style", "opacity:" + currentOpacity +";");
I later figured out the problem. The problem is that using setAttribute to set opacity also removed the positional settings I had given. Manually setting element.style.opacity made things work.
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 -->
Please, play with teh fiddle below. ONE bug goes as it should - turns its "head" and crawls in proper direction. But several bugs (starting with two and up) destroy it all. Jquery "each" returns coordinates twice so instead of two sets of coordinates for two bugs FOUR are generated.
$(document).ready(function () {
function bug() {
$('.bug').each(function () {
//var bugs = $('.bug').length;
var h = $(window).height() / 2;
var w = $(window).width() / 2;
var nh = Math.floor(Math.random() * h);
var nw = Math.floor(Math.random() * w);
//$this = $(this);
//var newCoordinates = makeNewPosition();
var p = $(this).offset();
var OldY = p.top;
var NewY = nh;
var OldX = p.left;
var NewX = nw;
var y = OldY - NewY;
var x = OldX - NewX;
angle = Math.atan2(y, x);
angle *= 180 / Math.PI
angle = Math.ceil(angle);
console.log(p);
$(this).delay(1000).rotate({
animateTo: angle
});
$(this).animate({
top: nh,
left: nw
}, 5000, "linear", function () {
bug();
});
});
};
bug();
});
http://jsfiddle.net/p400uhy2/
http://jsfiddle.net/p400uhy2/4/
As mentioned by #Noah B, the problem is that each "bug" is setting the loop for all "bugs".
I'd make bug() function per element, so that each "bug" can be set individually.
EDIT (#Roko C. Buljan comment)
function bug() {
// ... your code ...
// calculate animation time, so that each of bugs runs same fast in long and short distance:
var top_diff = Math.abs(OldY - nh),
left_diff = Math.abs(OldX - nw),
speed = Math.floor(Math.sqrt((top_diff * top_diff) + (left_diff * left_diff))) * 15;
$(this).animate({
top: nh,
left: nw
}, speed, "linear", function () {
// rerun bug() function only for that single element:
bug.call(this);
});
};
$('.bug').each(bug);
DEMO
The problem is that you had .each() calling a function with .each() in it...so each bug had the bug() callback. You just have to move the bug() call outside of the .each(){}. See fiddle: http://jsfiddle.net/p400uhy2/2/
I want to set dynamically with jQuery the css value of perspective-origin of a div. It's an absolute div(popup) with dynamic top and left (depends of window size, scroll etc...).
When I open the popup I want to do an animation in css with
transform: translateZ(-150px); But I have to set a perspective-origin as the center of the popup.
In javacript i did the following code
center: function () {
var $popup = this.$( '.popup' );
var $popupOverlay = this.$( '.popup-overlay' );
var wWidth = $( window ).width();
var wHeight = $( window ).height();
var dHeight = $( document ).height();
var popupWidth = $popup.width();
var popupHeight = $popup.height();
// Popup centered in the window at the scroll position
var popupTop = ( wHeight / 2 ) - ( popupHeight / 2 ) + $( document ).scrollTop();
var popupLeft = ( wWidth / 2 ) - ( popupWidth / 2 );
// If the popup height bigger than window height then the popup is not centered in the window but sticked at top
if ( popupHeight > wHeight ) {
popupTop += ( popupHeight - wHeight ) / 2;
}
// Set popupOverlay with and height as the document
$popupOverlay.width( wWidth );
$popupOverlay.height( dHeight );
// Set calculated top and left offset to the popup
$popup.css( {
'left': popupLeft,
'top': popupTop
} );
// Now calculate the transform-origin center of the popup
var xPos = popupLeft + popupWidth / 2 + 'px';
var yPos = popupTop + popupHeight / 2 + 'px';
var xyPos = xPos + ' ' + yPos;
console.log(xyPos);
// Set calculated transform-origin to the parent
this.$( '.popup-container' ).css( {
'perspective-origin': xyPos
} );
}
console.log xyPos return 538.5px 3024.5px so that should work...
When I inspect .popup-container I see no perspective-origin set.
For info I allready try to set -webkit-perspective-origin but didn't work too.
Does Jquery .css() methode handle perspective-origin?
Thanks in advance for your answers.
jQuery .css() method does handle perspective origin. For a quick reference that this feature works please check the source and you'll see perspective origin being set via style=""
http://jsfiddle.net/remix1201/d3hnpsgz/
HTML:
<div class="popup">This is a div class named popup.</div>
JS: (jQuery)
var xypos = "10px 20px"
$(".popup").css("perspective-origin", xypos);
$(".popup").css("color", "blue");
If you would like to make a fiddle to implement your function then we can take a better look at just exactly what is going wrong with your script.