Rotate image when scrolling - javascript

after using stackoverflow for plenty of help in the past I have a problem which will probably be easy for someone to solve…
I'm trying to rotate a background image when the user scrolls down the page, I have managed to get this far (with help from someone else's question and some helpful answers) but I need to slow down the rotation as its to fast. As far as I can tell I need to do something with the window height and use this to slow the rotation.
Heres my JSFiddle of how far I've got.
If anyone could help me out I'd be very grateful, my skills aren't quite up to scratch.
My code…
$(function() {
var rotation = 0,
scrollLoc = $(document).scrollTop();
$(window).scroll(function() {
var newLoc = $(document).scrollTop();
var diff = scrollLoc - newLoc;
rotation += diff, scrollLoc = newLoc;
var rotationStr = "rotate(" + rotation + "deg)";
$(".circle").css({
"-webkit-transform": rotationStr,
"-moz-transform": rotationStr,
"transform": rotationStr
});
});
})
CSS:
.container {
width:960px;
margin: 0 auto;
}
.circleWrap {
margin: 0 auto;
width:960px;
position:relative;
}
.circleContainer {
width: 970px;
position:fixed;
overflow:visible;
z-index:-50;
}
.circle{
background:url('http://www.wearerevolting.co.uk/dev/spin/moodring-col.jpg') no-repeat center;
width: 1772px;
height: 1772px;
margin-left: -400px;
}
.text {
z-index:50;
position:absolute;
height:2000px;
width:960px;
border:#000 thick solid;
}
<div class="container">
<div class="text">Content area</div>
</div>
<div class="circleWrap">
<div class="circleContainer">
<div class="circle"></div>
</div>
</div>
Cheers!

Change
var rotationStr = "rotate(" + rotation + "deg)";
to
var rotationStr = "rotate(" + rotation / 100 + "deg)";
where 100 is an arbitrary limiting value. Updated demo

Related

Need help scaling and rotating an image in a viewport

I have the code in this JSFidle - https://jsfiddle.net/pmi2018/smewua0k/211/
Javascript
$('#rotate').click(function(e) {
updateImage(90, 0)
console.log("rotation");
});
$('#zoom-in').click(function() {
updateImage(0, 0.1);
console.log("Zoomed in");
});
$('#zoom-out').click(function() {
updateImage(0, -0.1);
console.log("Zoomed out");
});
var zoomLevel = 1;
var rotation = 0;
var updateImage = function(angle, zoom) {
zoomLevel += zoom;
var img_scale = ' scale(' + zoomLevel + ') ';
rotation += angle;
if (rotation == 360) {
rotation = 0;
}
var str_rotation = ' rotate(' + rotation + 'deg) ';
console.log("rotation=" + str_rotation + " scale=" + img_scale);
var img = document.getElementById('sam');
img.style.transform = img_scale + str_rotation
//if (angle == 0) {
// img.style.transformOrigin = '0 0';
// img.style.transform = img_scale;
// }
// else {
// img.style.transformOrigin = 'center center';
// img.style.transform = str_rotation;
// }
}
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button>
<div id=imageblock>
<img id="sam" src="http://placekitten.com/g/250/250" />
</div>
<div>
<a id="rotate" href="#">Rotate 90 degrees</a>
</div>
CSS
#imageblock {
width: 300px;
height: 300px;
border: 1px solid #000000;
overflow: auto;
display: block;
}
#sam {
transform-origin: center, center;
}
The problem is I need the have the origin be upper left corner when I scale the image to keep the scaled image in the box; but the origin has to be center, center when I rotate the image to keep the image in the box. However the CSS articles I have read say when rotating and scaling an image, they have to be done together.
I tried applying the rotation and scale separately so I could set the origin correctly (the commented out code), but only the first transform fires, and not the second.
How can I rotate and scale the image in the #imagebox?
Thanks!
Mark
The reason why it "goes together" is because the transform property can only have one origin. So if you apply multiple transformations on a single object, they will all use the same origin.
An easy solution would be to put the image in a div. Then, use the zoom on the div, and the rotate on the image for exemple so that both can have different origins.
$('#rotate').click(function(e) {
updateImage(90, 0)
});
$('#zoom-in').click(function() {
updateImage(0, 0.1);
});
$('#zoom-out').click(function() {
updateImage(0, -0.1);
});
var zoomLevel = 1;
var rotation = 0;
var updateImage = function(angle, zoom) {
zoomLevel += zoom;
var img_scale = ' scale(' + zoomLevel + ') ';
rotation += angle;
if (rotation == 360) {
rotation = 0;
}
var str_rotation = ' rotate(' + rotation + 'deg) ';
// Here I modified the syntax just a bit, to use JQuery methods instead of pur Javascript. I hope you are ok with it
// I modify the image rotate property, and then the div scale property
$('#sam').css('transform',str_rotation)
$('#zoom').css('transform', img_scale);
}
#imageblock {
width: 300px;
height: 300px;
border: 1px solid #000000;
overflow: auto;
display: block;
overflow: hidden; /* To hide the scrollbar when you zoom in */
}
#zoom {
transform:scale(1);
transform-origin:top left;
}
#sam {
transform: rotate(0deg)
transform-origin: center center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="zoom-in">zoom in</button> <button type="button" id="zoom-out">zoom out</button>
<div id=imageblock>
<div id="zoom"> <!-- I added this div -->
<img id="sam" src="http://placekitten.com/g/250/250" />
</div>
</div>
<div>
<a id="rotate" href="#">Rotate 90 degrees</a>
</div>
Also, please note that there is no coma in transform-origin: center center;.
Ask them if you have any questions. I hope it helped !

Zoom container with div using transform translate and scale

I would like to zoom a container with divs on click, using only css transform and scale. The problem is, that it works only on first click, on second, third... my divs are translating strange. For me very thing important is to scale background.
var scale =0.5;
var interval = 5;
var line_weight =1;
$('document').ready(function(){
$('#container').click(function(){
$('.test').each(function(i){
var position = $(this).position();
var positionL=position.left;
var positionT=position.top;
var positionTscale=positionT*scale;
var positionLscale=positionL*scale;
var translateX = -(positionL-positionLscale)*(1/scale);
var translateY = -(positionT-positionTscale) *(1/scale);
$(this).css( 'transform', 'scale('+ scale +')' + ' translate('+ translateX + 'px'+','+ translateY +'px )' );
});
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' + line_weight/scale+ ' #ffffff 0, #ffffff ' + scale*interval+ 'px');
$(".test").css('border-right', (line_weight) +'px solid');
});
$('#container').dblclick(function(){
$(".test").css('transform', 'scale(1.0)');
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' +line_weight+' , #ffffff 0, #ffffff ' + interval + 'px');
$(".test").css('border-right', line_weight+'px solid');
});
});
</script>
body{
width: 19200px;
height: 10750px;
}
.test{
height: 200px;
width: 160px;
display: inline-block;
border-right: 1px solid;
background: repeating-linear-gradient(0deg, #000, #000 1px, #ffffff 0, #ffffff 5px);
}
#container{
width: 340px;
height: 400px;
}
.column{
display: inline-block;
}
<script src="jquery-3.0.0.min.js"></script>
<body>
<div id="container">
<div>
<div class="test" >
<p class="click">test1</p>
</div>
<div class="test" >
<p class="click">test2</p>
</div>
</div>
<div>
<div class="test">
<p class="click">test3</p>
</div>
<div class="test">
<p class="click">test4</p>
</div>
</div>
</div>
</body>
Code on jsfiiddle
What you need is just change the value in transform: scale(value).
I added two buttons for the example for you to zoom in and zoom out:
<p class="zoom _bigger">
zoom++
</p>
<p class="zoom _smaller">
zoom--
</p>
And here is all js to solve your problem:
$('document').ready(function(){
// We set value as 2, because further we will zoom with a half
var zoomValue = 2;
$('.zoom').on('click', function(){
if ($(this).hasClass('_bigger')) {
zoomValue++;
} else if (zoomValue > 2) {
zoomValue--;
} else {
return false;
}
$('#container').css('transform', 'scale(' + zoomValue * 0.5 + ')');
});
});
I used a half value for zooming, and you can play with it and set what you wish.
You can check out my example on jsfiddle.

style conflict between javascript and css

I have built a little element 3d rotator for infinite rotating in either direction on the X or Y axis. However I am running into what I think is a css style conflict. #face2 has a css property that rotates it -180deg . however its not being implemented by the browser.
is this a css conflict perhaps?
you can see the code and the effect in this code pen :
//declaring global variables
window.RotXFrontVal = 0; // by how much to rotate the X value of the front face
window.RotXBackVal = -180; // by how much to rotate the X value of the back face
window.RotYFrontVal = 0; // by how much to rotate the Y value of the front face
window.RotYBackVal = 180; // by how much to rotate the Y value of the back face
$(document).ready(function() {
//$('#face2').css({'transform': 'rotateX(-180deg)'}, 0);
//$('#face2').animate({'transform', 'rotateX(-180deg)'}, 0);
//$('#face2').animate({'transform': 'rotateX(-180deg)'}, 0);
var MyDivSlider = function() { // Here will come the Div Slider by Scroll
var scl = $.now(); // Take a time stamp to prevent function from triggering too often
$(document).on('DOMMouseScroll mousewheel', function MyScroll(event) {
if (($.now() - scl) > 500) {
if (event.originalEvent.detail > 0 || event.originalEvent.wheelDelta < 0) {
//Scroll Down
window.RotXFrontVal = window.RotXFrontVal - 180;
window.RotXBackVal = window.RotXBackVal - 180;
console.log("Down. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back");
}
//Up Scroll
else {
window.RotXFrontVal = window.RotXFrontVal + 180;
window.RotXBackVal = window.RotXBackVal + 180;
console.log("Up. Front: " + RotXFrontVal + "and" + RotXBackVal + " is Back");
}
$('#face2').css('transform', 'rotateX(' + RotXBackVal + 'deg)');
$('#face1').css('transform', 'rotateX(' + RotXFrontVal + 'deg)');
console.log('rotateX(' + RotXFrontVal + ')')
console.log('rotateX(' + RotXBackVal + ')')
scl = $.now();
}
});
}();
});
body { height:100%; overflow:hidden;}
#card {
height:300px;
width: 300px;
display: block;
position: relative;
transform-style: preserve-3d;
transition: all 1.5s linear;
perspective: 1000px;
}
#face1 {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: red;
backface-visibility: hidden;
transition: transform 1.5s;
z-index: 2;
}
#face2 {
display: block;
position: absolute;
width: 100%;
height: 100%;
background: blue;
backface-visibility: hidden;
transition: transform 1.5s;
z-index: 1;
transform: rotateX ( -180deg );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<body>
<div id="card">
<div id = "face1">Use the mouse scroll button to rotate me</div>
<div id = "face2">Use the mouse scroll button to rotate me</div>
</div>
</body>
It's because of the whitespace inbetween rotateX and (
try: transform: rotateX( -180deg );

Ball roll animation using jquery or CSS3

Is it possible to change this code so that the balls rolled out.
but:
Indicate the number of balls (for example 10).
Once rolled out one ball and stopped, then rolls out the next ball
(and gets close to another).
And that they rolling from the right side to the left side.
html
<div id="balls">
<img src="http://i058.radikal.ru/1407/0d/33cc119c6686.png" id="ball" />
</div>
css
body {
background: #383838;
}
#balls {
position: absolute;
}
#balls img {
position: absolute;
}
#ball {
width: 90px;
height: 90px;
left: 170px;
top: 45px;
}
jQuery
var diameter = $('#ball').height(),
perimeter = Math.PI * diameter;
var goLeft;
var times = 0;
var to = [600, 600];
function moveBalls() {
goLeft = !goLeft;
times++;
if (times > to.length) {
return false;
}
$('#balls').animate({
right: to[times]
}, {
duration: 2000,
step: rotateBall,
complete: moveBalls
});
}
moveBalls();
function rotateBall(distance) {
var degree = distance * 360 / perimeter;
$('#ball').css('transform', 'rotate(' + degree + 'deg)');
}
Example Here
jsBin demo
To get a better result you should have 3 elements for ball:
one that moves right with a static light source and shadow
rotate the inner DIV element
a SPAN with number -> inside the rotating DIV.
Use CSS3 transitions like I did.
<div id="balls">
<div class="ball blue"> <!-- THIS ONE JUST MOVES RIGHT -->
<div><span>7</span></div> <!-- THIS ONE ROTATES -->
</div>
<!-- MORE BALLS HERE -->
</div>
Following the above logic the CSS ends up being quite trivial:
.ball{
position:absolute;
left:-100px;
width:90px;
height:90px;
background:#004E99;
border-radius:50%;
box-shadow: 20px 30px 30px -10px rgba(0,0,0,0.4);
}
.ball>div{
position:absolute;
width:100%;
height:100%;
border-radius:50%;
}
.ball>div>span{
position:absolute;
left:23px;
top:14px;
width:45px;
height:45px;
border-radius:50%;
text-align:center;
line-height:45px;
font-size:24px;
font-weight:bold;
background:#fff;
}
/* YOUR COLORS */
.ball.blue{ background: radial-gradient(circle at 20px 20px, #09f, #001);}
JS/jQ:
var $ball = $('#balls > div'),
diameter = $ball.height(),
perimeter = Math.PI * diameter,
n = $ball.length,
i = 0,
itv;
itv = setInterval(function(){
if(i>n)clearInterval(itv);
rotateBall( 500-(diameter*i) );
i++;
},2000);
function rotateBall(distance) {
var degree = distance * 360 / perimeter;
$ball.eq(i).css({
transition: "2s",
transform: 'translateX('+ distance +'px)'
}).find('div').css({
transition: "2s",
transform: 'rotate('+ degree +'deg)'
});
}

div scale to preserve aspect ratio

I have a layout like so:
HTML
<div id="container">
<div id="zoomBox">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
CSS
#container { width:100%; }
#box { height:1000px;width:920px; }
What I am trying to do is scale my container and the contents to preserve the aspect ratio it is currently in. Right now I use the transform: scale() and it works great but I am having serious issues with it working in Internet Explorer.
This is my code so far. Does anyone have any other suggestions in making this work nicely in IE?
function zoomProject(percent)
{
$maxWidth = $("#container").width();
if(percent == 0)
percent = $maxWidth/920;
$("#zoomBox").css({
'transform': 'scale(' + percent + ')',
'-moz-transform': 'scale(' + percent + ')',
'-webkit-transform': 'scale(' + percent + ')',
'-ms-transform': 'scale(' + percent + ')'
});
}
I don't have jquery set up but an example using raw html and javascript. It probaly wont run on IE as is (older ie doesn't use some of the same syntax but has the same functionality) but once you switch it over to jquery it should be fine.
Code:
function zoomProject(ratio) {
var i, height;
var boxes = document.getElementsByClassName("box");
for (i=0;i<boxes.length;i++) {
height = (boxes[i].offsetWidth * ratio) + "px";
boxes[i].style.height = height;
}
}
zoomProject(.1);
.container { background: red; width: 100%; height: 100%; }
.box { background: blue; width: 100%; border: 1px solid white;}
Try without transform:
new_width = width * percent / 100;
new_height = height * percent / 100;
$("#zoomBox").css('width',new_width);
$("#zoomBox").css('height',new_height);

Categories