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.
Related
Attempting to transform an images scale (zoom) BUT maintain it inside it's parents left and top div so only trying to transform it down and to the right. Setting the transform orgin does not seem to work, what am I missing?
the following code zooms the image on each button click, but pushes the left and top out of the parent div.
$('element').click(function{
$('#element').css({'transform':'scale(' + scale + ')' });
$('#element').css({'transform-orgin':'top left'});
})
<div style "max-wdith:1080px; height: 700px; overflow-x:scroll; overflow-y:scroll">
<img id="element" src=" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" " class="img-flud">
</div>
You can try the below code
var x = 400 + 'px';
var y = 300 + 'px';
$('#element').css({
'transform-origin': x + ' ' + y + ' 0px',
'-webkit-transform-origin': x + ' ' + y + ' 0px'
});
Updated answer!
const btn = document.querySelector('button');
function zoomIn(e) {
const scale = 0.1;
const img = document.querySelector('#my-image');
$('#my-image').css({transformOrigin: "top left", transform: 'scale(' + scale + ')'});
}
btn.addEventListener('click', zoomIn);
div {
width: 400px;
height: 400px;
border: 1px solid black;
overflow: hidden;
float: left;
}
div > img {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img id="my-image" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" />
</div>
<button>Zoom In</button>
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 !
I am working on the below code. Why am I not able to decrease the height of the #map?
As you can see the .btn-enlarge is enlarging the height of the image but the .btn-shrinkis not decreasing the height
$(function() {
var unit = 10;
$(".btn-enlarge").on("click", function(){
unit = unit+ unit;
$("#map").animate({
'height': $("#map").height()+unit+ 'px'
});
});
$(".btn-shrink").on("click", function(){
unit = unit+ unit;
$("#map").animate({
'height': $("#map").height()+'-'+unit+ 'px'
});
});
});
#map {
width: 300px;
height: 300px;
border: 1px solid rgb(0, 0, 0);
cursor: move;
overflow: hidden;
Background-image: url('https://i.pinimg.com/originals/dd/a5/17/dda5177a3db95a93c0c84ff6847fda23.jpg');
background-repeat: no-repeat;
background-size:cover;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="btn-shrink">-</button>
<button type="button" class="btn-enlarge">+</button>
<div id="map"></div>
You can always use += and -=
jQuery(function( $ ) {
var step = 10;
$(".btn-enlarge, .btn-shrink").on("click", function() {
var sym = $(this).is(".btn-enlarge") ? "+=" : "-=";
$("#map").animate({height: sym + step});
});
});
#map {
width: 300px;
height: 300px;
border: 1px solid rgb(0, 0, 0);
background: url('https://i.stack.imgur.com/O724n.jpg') 50% 50% / contain no-repeat;
}
<button type="button" class="btn-shrink">-</button>
<button type="button" class="btn-enlarge">+</button>
<div id="map"></div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
The above's
$("#map").animate({height: sym + step});
translates to:
$("#map").animate({height: "+=10"}); // or
$("#map").animate({height: "-=10"}); // depending on the clicked button
I have the following as my code which gives me my desired effect.
#overlay {
background-color: rgba(0, 0, 0, 0.66);
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
clip-path: polygon( 0% 0%, /*exterior top left*/
0% 100%, /*exterior bottom left*/
220px 100%, /*overlapping point exterior 1*/
220px 50%, /*overlapping point interior 1*/
220px 310px, /*interior top left*/
683px 310px, /*interior top right*/
683px 450px, /*interior bottom right*/
220px 450px, /*overlapping point interior 2*/
220px 100%, /*overlapping point exterior 2*/
100% 100%, /*exterior bottom right*/
100% 0%);
/*exterior top right*/
}
<body>
<div>Some background</div>
<div id="overlay">
</div>
<div id="closeButton">
<p>
Close
</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
function main() {
$("#overlay").hide();
$("#overlay").fadeIn(500);
$("#closeButton").on("click", function() {
$("#overlay").toggle();
});
}
$(document).ready(main);
</script>
</body>
I want to know if I could write a function to do the same thing that takes in an array of coordinates so that I don't have to hard code it in every time I want to move the window. It would trigger when the closeButton is pressed.
You could certainly compute a polygon string in JavaScript, then set that style on the element. Here's an example function that can take 2 pixel coordinates to create a similar polygon:
#overlay {
background-color: rgba(0, 0, 0, 0.66);
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<body>
<div>Some background</div>
<div id="overlay">
</div>
<div id="closeButton">
<p>
Close
</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
// Copy this function:
function generatePoly(p1, p2) {
var a = p1[0] + 'px';
var b = p1[1] + 'px';
var c = p2[0] + 'px';
var d = p2[1] + 'px';
return 'polygon(' + [
'0% 0%',
'0% 100%',
a + ' 100%',
a + ' 50%',
a + ' ' + b,
c + ' ' + b,
c + ' ' + d,
a + ' ' + d,
a + ' 100%',
'100% 100%',
'100% 0%'
].join(', ') + ')';
}
function main() {
// Run this when you want to set the polygon:
$("#overlay").css('clip-path', generatePoly([40, 80], [120, 200]));
$("#overlay").hide();
$("#overlay").fadeIn(500);
$("#closeButton").on("click", function() {
$("#overlay").toggle();
});
}
$(document).ready(main);
</script>
</body>
I'm working on a site based on this: http://inner.geek.nz/javascript/parallax/
All's well except I'm getting a jump down (by whatever px is set in calcParallax(xx, x, posY))
on scroll. This number should be where the image ends not where it begins — it should begin scrollTop or 0. Not sure what I'm doing wrong, I've pretty much taken the structure verbatim from the above link without the #cloud object or relevant script.
Here's what I have:
<script type="text/javascript">
function calcParallax(tileheight, speedratio, scrollposition) {
return ((tileheight) - (Math.floor(scrollposition / speedratio) % (tileheight+1)));
}
window.onload = function() {
window.onscroll = function() {
var posX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : window.pageXOffset;
var posY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : window.pageYOffset;
var ground = document.getElementById('ground');
var groundparallax = calcParallax(53, 8, posY);
ground.style.backgroundPosition = "0 " + groundparallax + "px ";
document.getElementById('javascriptcode').onscroll = function() {
var posX = (this.scrollLeft) ? this.scrollLeft : this.pageXOffset;
var j = calcParallax(53, 16, posX);
console.log('scroll js: '+ j);
document.getElementById('javascriptcode').style.backgroundPosition = j + "px 0";
}
}
</script>
Any help would be much appreciated
Use this example instead. It uses a different jQuery that seems more stable and does not jump around like the script from inner geek.
http://www.stevefenton.co.uk/cmsfiles/assets/File/backgroundparallax.html
I put together a demo on something similar while trying to minimize scripting in the scroll event... I've found that it's jumpy in Firefox and Chrome, and oddly smooth as silk in IE.
Even this game website that uses a combination of Mootools and CSS transitions is a bit jumpy.
CSS
/* Tiled background image */
body {
margin: 0;
padding: 0;
/* Use height of header image for top position */
background: #000 url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bgtile.jpg) left 1080px repeat-y;
}
/* Top background image (1920x1080) */
#wrapper {
position: relative;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bg1.jpg) center top repeat-x;
z-index: 100;
}
/* Page Title image */
#header {
height: 350px;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/title.png) center 40px no-repeat;
}
/* Content Block with 55% opacity background image */
.block {
width: 600px;
height: 500px;
margin: 20px auto;
border: #333 1px solid;
padding: 20px;
background: url(http://i201.photobucket.com/albums/aa236/Mottie1/testsite/forums/bg-black-55.png);
}
.block h3 {
font-family: 'Arial Black', Gadget, sans-serif;
font-size: 130%;
}
HTML
<body> <!-- contains repeated background image -->
<div id="wrapper"> <!-- contains top image -->
<div id="header"></div> <!-- contains the page title image -->
<div class="block"> <!-- contains 55% opacity background image -->
<h3>Block 1</h3>
<div class="content">Content 1.</div>
</div>
<div class="block">
<h3>Block 2</h3>
<div class="content">Content 2.</div>
</div>
<div class="block">
<h3>Block 3</h3>
<div class="content">Content 3.</div>
</div>
<div class="block">
<h3>Block 4</h3>
<div class="content">Content 4.</div>
</div>
<div class="block">
<h3>Block 5</h3>
<div class="content">Content 5.</div>
</div>
</div>
</body>
Script
$(document).ready(function(){
// defaults
var st, win = $(window)[0],
body = $('body')[0],
doc = (jQuery.support.boxModel) ? document.documentElement : document.body,
wrap = $('#wrapper')[0],
// Set top background image height here
imgH = 1080; // top image height
// vertical parallax scroll
$(win).scroll(function(){
st = (win.pageYOffset || doc.scrollTop );
if (st < imgH) { wrap.style.backgroundPosition = 'center ' + (st/4) + 'px'; } // limit moving top image only when in view
body.style.backgroundPosition = 'left ' + ( imgH + st/4) + 'px';
});
});
Change your 53 to the exact height of each element.
The only thing I can't figure out about this script is it jumps slightly vertically when I change it to a scroll left function.
var element = document.getElementById('element');
var elementparallax = calcParallax(7000, .5, posX);
element.style.backgroundPosition = " 0" + elementparallax + "px";
};
P.S. You can change the vertical scroll to horizontal by changing posY to posX and in = "0_" + elementparalax to = "_0"