Transform orgin not being implemented - javascript

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>

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 !

Creating variables in Javascript to manipulate the CSS box-shadow

I am creating a CSS editor using Javascript. I would like the User to be able to change the attributes of the CSS box-shadow. I imagine the function would look something like this:
var box = document.getElementById("boxDiv");
var h-offset; //= getUserInput (= document.getElementById("textareaID").value;)
var v-offset; //= getUserInput
var blur; //= getUserInput
var spread; //= getUserInput
var color; //= getUserInput
box.style.boxShadow =; //(h-offset,v-offset,blur,spread,color)
I am not sure how to format the String in a way the CSS box-shadow can understand it.
Thanks!
You can just concatenate the strings together. Keep in mind, that you need to validate the user input first. Otherwise, the box-shadow is not properly shown, if the user inserts a wrong value.
box.style.boxShadow = offsetX + ' ' + offsetY + ' ' + blurRadius + ' ' + spreadRadius + ' ' + color;
With ES6, you can also use template strings:
box.style.boxShadow = `${offsetX} ${offsetY} ${blurRadius} ${spreadRadius} ${color}`;
Here is a live example:
function apply() {
var box = document.getElementById('box');
var offsetX = document.getElementById('offsetX').value;
var offsetY = document.getElementById('offsetY').value;
var blurRadius = document.getElementById('blurRadius').value;
var spreadRadius = document.getElementById('spreadRadius').value;
var color = document.getElementById('color').value;
box.style.boxShadow = offsetX + ' ' + offsetY + ' ' + blurRadius + ' ' + spreadRadius + ' ' + color;
}
#box {
width: 100px;
height: 100px;
background: #f2f2f2;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
input {
display: block;
}
<div id="box"></div>
<input id="offsetX" placeholder="offsetX" />
<input id="offsetY" placeholder="offsetY" />
<input id="blurRadius" placeholder="blurRadius" />
<input id="spreadRadius" placeholder="spreadRadius" />
<input id="color" placeholder="color" />
<button onclick="apply()">Apply</button>
Thanks. I realized that I was not formatting the String correctly.
What I was coding:
box.style.boxShadow = String(h-offset + v-offset + blur + spread + color);
What I needed to code:
box.style.boxShadow = String(h-offset + " " + v-offset + " " + blur + " " + spread + " " + color);
Almost a 'Well Duh' moment XD
var first = "10px";
var second = "20px";
var third = "red";
$("#bshadow_jquery").css('box-shadow', first + " " + second + " " + third);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<style>
#bshadow_css {
border: 1px solid;
padding: 10px;
box-shadow: 5px 10px;
}
#bshadow_jquery {
border: 1px solid;
padding: 10px;
}
</style>
</head>
<body>
<h2>box-shadow css: 5px 5px #990000:</h2>
<div id="bshadow_css">
<p>this is a block-shadow by css</p>
</div>
<hr style="margin: 50px 0px">
<h2>box-shadow jquery: 5px 5px #990000:</h2>
<div id="bshadow_jquery">
<p>this is a block-shadow by JQuery</p>
</div>
</body>
</html>

Change amount from px to percent based

I am trying to create a carousel with a sliding effect. The basic setup is I have 2 div's wrapping around the sliding content. The first div's width (the outerWrapper) is the size of all slides width together. The next div's width (the innerWrapper) is the size of 1 div.
When it's supposed to change slides, the innerWrapper get's a translation of x amount and it animates from the css transition.
I have everything working, but there's one thing I want to change. I want to change from pixel to percent.
Line 29:
innerWrapper.style.transform = 'translateX(-' + imgWidth * targetIndex + 'px)';
I tried a lot of things, but nothing worked. The only thing that worked was targetIndex * 20 + %, but that only works for 5 divs. It's not a concrete solution. How can I make the translateX percentage based?
JSFiddle
var trigger = document.getElementsByClassName('trigger'),
outerWrapper = document.createElement('div'),
innerWrapper = document.createElement('div'),
slide = document.getElementsByClassName('slide'),
parentElm = slide[0].parentNode,
imgWidth = slide[0].offsetWidth,
lastElm = trigger.length - 1,
previousSelectedIndex = 0;
innerWrapper.id = 'innerWrapper';
outerWrapper.id = 'outerWrapper';
trigger[0].className += ' selected';
innerWrapper.style.width = imgWidth * (lastElm + 1) + 'px';
while (slide.length) {
innerWrapper.appendChild(slide[0]);
}
for (var i = 0; i < trigger.length; i++) {
trigger[i].addEventListener('click', function(e) {
clickEvent(e);
})
}
function clickEvent(e) {
if (!hasClass(e.target, 'selected')) {
var targetIndex = [].slice.call(trigger).indexOf(e.target);
innerWrapper.style.transform = 'translateX(-' + imgWidth * targetIndex + 'px)';
e.target.className += ' selected';
removeClass(trigger[previousSelectedIndex], 'selected');
previousSelectedIndex = targetIndex;
}
}
outerWrapper.appendChild(innerWrapper);
parentElm.appendChild(outerWrapper);
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
ele.className = ele.className.replace(reg, ' ');
}
}
#outerWrapper {
float: left;
width: 270px;
height: 266px;
overflow: hidden;
}
#innerWrapper {
position: relative;
display: flex;
transition: transform 0.7s cubic-bezier(0.45, 0.05, 0.55, 0.95);
}
ul.triggers li {
float: left;
margin: 0 5px;
font: bold 16px arial;
cursor: pointer;
background-color: #ccc;
padding: 10px;
}
ul.triggers li.selected {
background-color: orange;
}
<img class="slide" width="270" src="http://i.imgur.com/XyWadkY.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/OpP86hg.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/oWbhwWT.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/IXcqVB1.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/OpP86hg.jpg" />
<ul class="triggers">
<li class="trigger">1</li>
<li class="trigger">2</li>
<li class="trigger">3</li>
<li class="trigger">4</li>
<li class="trigger">5</li>
</ul>
Try this,
innerWrapper.style.transform = 'translateX(-' + (targetIndex*(100/document.getElementsByClassName("slide").length)) + '%)';

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 );

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