jQuery: Inaccuracy with scrollLeft when scaled - javascript

I have a scrollable container with links and thumbnails - scrollLeft to thumbnail depending on the link clicked which works fine, normally.
However, when I scale the main container with transform, scrollLeft scrolls to wrong position.
Any ideas how to resolve this?
scroll: function(){
var chapterName = this.chapter.getAttribute('data-chapter');
var thumbnail = $('.thumbnail-content[data-chapter="'+chapterName+'"]').parent();
if ( !$(this.chapter).hasClass('active-chapter') ){
$('.active-chapter').removeClass('active-chapter');
$('#thumbnail-container').animate({
'scrollLeft' : '+='+thumbnail.position().left
},{
duration : 400,
easing : 'easeOutSine'
});
$(this.chapter).addClass('active-chapter');
}
}
reScale: function() {
var windowHeight = $(window).height() - 20;
if (windowHeight <= 827) {
$('#viewer-container').addClass('scale scale075');
}
}
CSS:
.scale075 {
-webkit-transform: scale(0.75); /* Chrome, Safari 3.1+ */
-webkit-transform-origin: 50% 50%;
-moz-transform: scale(0.75); /* Firefox 3.5+ */
-moz-transform-origin: 50% 50%;
-ms-transform: scale(0.75); /* IE 9 */
-ms-transform-origin: 50% 50%;
-o-transform: scale(0.75); /* Opera 10.50-12.00 */
-o-transform-origin: 50% 50%;
transform: scale(0.75); /* Firefox 16+, IE 10+, Opera 12.10+ */
transform-origin: 50% 50%;
}
Here is a fiddle

$('#thumbnail-container').animate({
'scrollLeft' : thumbnail[0].offsetLeft/*change here*/
},{
duration : 400,
easing : 'easeOutSine'
});
I think,in this ticket,it's better to use absolute position then relative position.
And then offsetLeft has no relation with transform,so everything work fine.
fiddle

You can resolve this if you know the scale in the script.
I modded your fiddle to fix it and tried to fix your example code.
Here is a fiddle
So when you transform to say 0.75 you set a variable to 0.75 then when you set the scrollLeft you multiply the thumbnail position with 1/scale
var scrollScale = 1;
...
scroll: function(){
var chapterName = this.chapter.getAttribute('data-chapter');
var thumbnail = $('.thumbnail-content[data-chapter="'+chapterName+'"]').parent();
if ( !$(this.chapter).hasClass('active-chapter') ){
$('.active-chapter').removeClass('active-chapter');
$('#thumbnail-container').animate({
'scrollLeft' : '+='+thumbnail.position().left * (1/scrollScale)
},{
duration : 400,
easing : 'easeOutSine'
});
$(this.chapter).addClass('active-chapter');
}
}
reScale: function() {
var windowHeight = $(window).height() - 20;
scrollScale = 1;
if (windowHeight <= 827) {
$('#viewer-container').addClass('scale scale075');
scrollScale = 0.75;
}
}
Hope that solves your problem or give you an idea how to solve it more dynamically.
So the reason for this is that position().left uses your transform when it recalculates position.. But scrollLeft dont check transform. so you recalculate position so they use the same scale.

Related

Element transform scale maintained after transform rotation occurrs

I have an element I am zooming in (one button) and then rotating (another button)
When I zoom in on the element the scale gets updated, then when I go to rotate element the scale is not kept from the zoom (but it really is, I can see the value is maintained browser debug) but it zooms back out to the initial scale when rotate is clicked.
let spin = 0;
let zoom = 1;
$('#SpinRight').click(function(){
//I know for a fact scale keeps value here, but zooms back out to original size when I //click spin
spin += 25;
$('#element').css({'transform' : 'rotate(' + spin + 'deg'});
})
$('#Magnify').click(function(){
zoom += 0.1;
$('#element').css({'transform' : 'scale(' + zoom + ')'});
})
transform rules don't stack, so if you do:
transform: rotate(45deg);
transform: scale(0.5);
The scale transform replaces the rotate rule, it doesn't add to it. If you want both you need to specify them both in a single rule:
transform: rotate(45deg) scale(0.5);
You could keep track of the rotation and scale in css properties and then have a rule that applies them both. (Or just apply them the way you're already doing it, but do both for each update.)
const demo = document.querySelector('.demo');
let rotate = 0;
let scale = 1;
document.querySelector('.rotate').addEventListener('click', () => {
demo.style.setProperty('--rotate', `${rotate += 10}deg`);
});
document.querySelector('.scale').addEventListener('click', () => {
demo.style.setProperty('--scale', scale += 0.1);
});
.demo {
--rotate: 0;
background: skyblue;
width: 100px;
height: 100px;
transform: rotate(var(--rotate, 0)) scale(var(--scale, 1));
}
button {
position: relative; /* just so the buttons stay on top */
}
<div class="demo"></div>
<button class="rotate">Rotate</button>
<button class="scale">Scale</button>

Scale down / up every html element when window resize

I would like to keep the same layout instead of responsive, but scale up / down everything when I resize the window screen.
The font / image may be very small when the screen size is small but that does not matter. The base width is 1920px:
And the site I am working on is:
kotechweb.com/new_focus/page/about_us
I have attempted in the header.php
<meta id="meta" name="viewport" content="width=device-width; initial-scale=0.1; maximum-scale=2.0; user-scalable=0;">
And Jquery
$(window).resize(function () {
var width = $(window).innerWidth() / 1920;
$("#meta").attr("content", "width=device-width; initial-scale=" + width + "; maximum-scale = 1.0; user - scalable = 0; ");
});
But it seems no effect for the desktop browser , thanks for helping.
try to add css to your body
-moz-transform: scale(0.5);
-webkit-transform: scale(0.5);
transform: scale(0.5);
For your seconde question :
you said your base width is "1920" so 1920 is the 100%
So what you have to do is
calculateNewScale(); // if the user go to the page and his window is less than 1920px
$(window).resize(function ()
{
calculateNewScale();
});
function calculateNewScale()
{
var percentageOn1 = $(window).width() / 1920) ;
$("body").css(
{
"-moz-transform": "scale("+percentageOn1 +")",
"-webkit-transform": "scale("+percentageOn1 +")",
"transform": "scale("+percentageOn1 +")
});
}
test it and let me know if it works

How do I zoom out a whole website using jQuery or CSS?

I would like to make my website like 80% smaller. i.e. zoom out images, fonts, everything to 80% of its current size. Is there any way to do this using jQuery or CSS?
I tried body { zoom:80% } but it works only for Chrome.
CSS solution:
body {
-moz-transform: scale(0.8, 0.8); /* Moz-browsers */
zoom: 0.8; /* Other non-webkit browsers */
zoom: 80%; /* Webkit browsers */
}
Supported on all major browsers http://caniuse.com/#feat=css-zoom
For Firefox, fallback is transform-scale http://caniuse.com/#feat=transforms2d
Here a more flexible solution using CSS transform: scale() and JavaScript / jQuery:
<!-- Trigger -->
<ul id="zoom_triggers">
<li><a id="zoom_in">zoom in</a></li>
<li><a id="zoom_out">zoom out</a></li>
<li><a id="zoom_reset">reset zoom</a></li>
</ul>
<script>
jQuery(document).ready(function($)
{
// Set initial zoom level
var zoom_level=100;
// Click events
$('#zoom_in').click(function() { zoom_page(10, $(this)) });
$('#zoom_out').click(function() { zoom_page(-10, $(this)) });
$('#zoom_reset').click(function() { zoom_page(0, $(this)) });
// Zoom function
function zoom_page(step, trigger)
{
// Zoom just to steps in or out
if(zoom_level>=120 && step>0 || zoom_level<=80 && step<0) return;
// Set / reset zoom
if(step==0) zoom_level=100;
else zoom_level=zoom_level+step;
var scale = zoom_level / 100;
// Set page zoom via CSS
$('body').css({
-moz-transform: scale(scale, scale); /* Moz-browsers */
transform: 'scale('+(scale)+')', // set zoom
transformOrigin: '50% 0' // set transform scale base
});
// Adjust page to zoom width
if(zoom_level>100) $('body').css({ width: (zoom_level*1.2)+'%' });
else $('body').css({ width: '100%' });
// Activate / deaktivate trigger (use CSS to make them look different)
if(zoom_level>=120 || zoom_level<=80) trigger.addClass('disabled');
else trigger.parents('ul').find('.disabled').removeClass('disabled');
if(zoom_level!=100) $('#zoom_reset').removeClass('disabled');
else $('#zoom_reset').addClass('disabled');
}
});
</script>
var zoom_level=100;
// Click events
$('#btn_zoom_in').click(function() { zoom_page(10, $(this)) });
$('#btn_zoom_out').click(function() { zoom_page(-10, $(this)) });
$('#btn_zoom_reset').click(function() { zoom_page(0, $(this)) });
function zoom_page(step, trigger)
{
if( $('#form_width').val()<1){
alert('Please Choose your Template and Design Width');
$('#change_product').focus();
return false;
}
var max_zoom = 180;
var min_zoom = 10;
if(zoom_level>=max_zoom && step>0 || zoom_level<=min_zoom && step<0) return;
if(step==0) zoom_level=100;
else zoom_level=zoom_level+step;
var scale = zoom_level / 100;
var selector = '.panel-body';
$(selector).css({"transform":"scale("+scale+")","transformOrigin":"left top"});
zoom_level==max_zoom ? $('#btn_zoom_in').addClass('disabled') : $('#btn_zoom_in').removeClass('disabled');
zoom_level==min_zoom ? $('#btn_zoom_out').addClass('disabled') : $('#btn_zoom_out').removeClass('disabled');
if( zoom_level==100 ) $('#btn_zoom_reset').addClass('disabled');
if( zoom_level!=100 ) $('#btn_zoom_reset').removeClass('disabled');
}

center image in simple jquery zoom plugin

I'm trying to write a very very simple zoom plugin that should have just a button to zoom in, zoom out, and the pan function to move the image around.
For now I've writte the part to zoom in and zoom out.
My problem is that I can't find a way to center the image inside the "zoombox".
This is my code so far:
$.fn.zoom = function() {
var img = this;
img.attr("style", "-ms-transform: scale(1); -ms-transform-origin: 0% 0%; -webkit-transform: scale(1); -webkit-transform-origin: 0% 0%").wrap('<div style="width: 400px; height: 400px; overflow: hidden;" class="zoombox" data-scale="1"></div>');
$("body").on("click.zoom", ".zoomin, .zoomout", function() {
if( $(this).hasClass("zoomin") ) {
var zoomFactor = (Number(img.parent().attr("data-scale")) + 0.1).toFixed(1);
} else {
var zoomFactor = (Number(img.parent().attr("data-scale")) - 0.1).toFixed(1);
}
img.parent().attr("data-scale", zoomFactor);
console.log(zoomFactor);
img.css({"-webkit-transform": "scale(" + zoomFactor + ")", "-ms-transform":"scale(" + zoomFactor + ")"});
});
};
Fiddle:
http://jsfiddle.net/xM7r4/1/
I know the style is not the best but I'm just trying to make it works without think about the style of the code.
How can I center the image inside the box, thinking that I will have to apply a pan effect later that will change the transform-origin values?
PS: I care about compatibility only on Chrome and IE9 for now.
edit for comment
You are correct. Here I've updated to work with transform-origin. It takes the dimensions of the containing div and divides by two (to get the centerpoint of the containing div) and passes these into the image's css transform-origin property:
http://jsfiddle.net/xM7r4/23/
I've tested with different dimensioned images, and it works.
original
You'll need to move the image using margin-left and margin-top depending on if you are zooming in or out.
http://jsfiddle.net/xM7r4/21/
Since you are increasing your image by a scale of 1%, you need to move the margins accordingly, negative for zoom-in, position for zoom-out.
$("body").on("click.zoom", ".zoomin, .zoomout", function() {
var imgWidth = $(img).width();
var imgHeight = $(img).height();
var scaleWidth = Math.floor(imgWidth * 0.01);
var scaleHeight = Math.floor(imgHeight * 0.01);
if( $(this).hasClass("zoomin") ) {
var zoomFactor = (Number(img.parent().attr("data-scale")) + 0.1).toFixed(1);
moveLeft -= scaleWidth;
moveTop -= scaleHeight;
} else {
var zoomFactor = (Number(img.parent().attr("data-scale")) - 0.1).toFixed(1);
moveLeft += scaleWidth;
moveTop += scaleHeight;
}
console.log(moveTop);
console.log(moveLeft);
img.parent().attr("data-scale", zoomFactor);
console.log(zoomFactor);
img.css({"-webkit-transform": "scale(" + zoomFactor + ")", "-ms-transform":"scale(" + zoomFactor + ")", "marginLeft": moveLeft, "marginTop": moveTop});
});

why my width and height are changing when I change my view on my tablet?

My app is made for only landscape view, and what I need is that when it's on portrait it will rotate and show me the landscape view so that i can force the user to see the app in landscape. Though I have a problem, and I am very confused right now. Maybe I am not seeing the problem.
var mql = window.matchMedia("(orientation: portrait)");
var all = document.getElementById("slider-view");
var winWidth = 0;
var winHeight = 0;
// If there are matches, we're in portrait
if(mql.matches) {
// Portrait orientation
$(all).addClass('portrait-transform');
$(all).css('height', window.innerWidth);
$(all).css('width', window.innerHeight);
$(all).css('top', (window.innerHeight - window.innerWidth) / 2);
$(all).css('left', (window.innerWidth - window.innerHeight) / 2);
winWidth = window.innerHeight;
winHeight = window.innerWidth;
alert('height '+ $(all).css('height')+' width '+$(all).css('width')+' top '+$(all).css('top')+' left '+$(all).css('left'));
} else {
// Landscape orientation
$('#slider-view').removeClass('portrait-transform');
all.style.height = window.innerHeight + "px";
all.style.width = window.innerWidth + "px";
winWidth = window.innerWidth;
winHeight = window.innerHeight;
alert('height '+ $(all).css('height')+' width '+$(all).css('width')+' top '+$(all).css('top')+' left '+$(all).css('left'));
}
// Add a media query change listener
mql.addListener(function(m) {
if(m.matches) {
// Changed to portrait
$(all).addClass('portrait-transform');
$(all).css('height', window.innerWidth);
$(all).css('width', window.innerHeight);
$(all).css('top', (window.innerHeight - window.innerWidth) / 2);
$(all).css('left', (window.innerwidth - window.innerheight) / 2);
alert('height '+ $(all).css('height')+' width '+$(all).css('width')+' top '+$(all).css('top')+' left '+$(all).css('left'));
}
else {
// Changed to landscape
$(all).removeClass('portrait-transform');
$(all).css('height', window.innerWidth);
$(all).css('width', window.innerHeight);
$(all).css('top', 0);
$(all).css('left', 0);
var winWidth = window.innerWidth;
var winHeight = window.innerHeight;
}
});
And I have this for the css
.portrait-transform {
/* portrait-specific styles */
-webkit-transform: rotate(90deg); /* WebKit */
-webkit-transform-origin: 50% 50%;
-moz-transform: rotate(90deg); /* Mozilla */
-moz-transform-origin: 50% 50%;
-o-transform: rotate(90deg); /* Opera */
-o-transform-origin: 50% 50%;
-ms-transform: rotate(90deg); /* Internet Explorer */
-ms-transform-origin: 50% 50%;
transform: rotate(90deg); /* CSS3 */
transform-origin: 50% 50%;
}
I need help to understand why my height and width values change when I change the view.

Categories