Rotation and Translation of Image Javascript - javascript

I have 4 images connected to each other which form a big image. My task is to rotate the big image to a certain angle that is entered by the user.
Now, to rotate the full image, I need to rotate the smaller connected images and then translate them accordingly so that the full images seems to be rotated.
But can't get the translation coordinates properly. Please help me out with that.
Also, if there is any other way to do this, you can tell me that as well.
The code can be found here -
https://jsfiddle.net/e4qp6btx/1/
document.getElementById("img1").style.transform = "translate(" + x + "px," + y + "px) rotate(" + angle + "deg)" ;
Edit -
I actually want to rotate and translate individual images rather than rotating the whole container.

I would just target and rotate the container instead. When trying on Mac Firefox, however, the smaller images seemed to get small spaces between them.
rotateImage() {
var angle = document.getElementById('angle').value || 0; //angle to be rotated by
angle = angle % 360 + 'deg';
document.querySelector('.container').style.transform = `rotate(${angle})`;
}
I would also use a CSS variable to set the angle, and then update the variable, instead of using inline style to change the transform: rotate value.
Finally, I would give the container a unique id.

Second solution.
Rotation originates from the center of the image by default. You can change this by setting transform-orgin. The following CSS will make the images rotate like they should, so you don't need to translate them. You should probably frankenstein together my two answers, because you barely need any code for your rotateImage() to work.
#img1 {
transform-origin: bottom right;
}
#img2 {
transform-origin: bottom left;
}
#img4 {
transform-origin: top right;
}
#img3 {
transform-origin: top left;
}
Do note: you mixed up the positions of #img4 and #img3, where #img4 comes before #img3, hence these images having the transform-origins switched around.
An added bonus:
I feel it's kinda wasteful to set the same value on four different elements, so I would suggest to use a CSS variable on .container to store the rotation value on all images. It would be easier to test different values in the Inspector if you do it like that.
CSS
.container {
--image-rotation: 0deg;
width:500px;
height:500px;
padding: 50px;
}
img {
width:100%;
height:100%;
transform: rotate(var(--image-rotation));
}
Javascript
rotateImage() {
const imgContainer = document.querySelector('.container');
let angle = document.getElementById('angle').value || 0; //angle to be rotated by
angle = angle % 360 + 'deg';
imgContainer.style.setProperty('--image-rotation', angle);
}
https://jsfiddle.net/mg46dz7h/

Related

How to maintain position after changing div transform-origin?

Let's say I had the following code:
function rotate() {
const elem = document.querySelector(".rect");
elem.style.transformOrigin = "top right";
}
.rect {
width: 200px;
height: 100px;
transform: rotateZ(45deg);
background-color: #ddd;
transform-origin: center;
}
<div class="rect"></div>
<button onclick="rotate()">Rotate</button>
You'll notice that when you click the Rotate button that the rectangle's transform-origin property changes from center to top right. As a result, the rectangle moves, because it is now rotated around a different origin.
Is it possible to have the rectangle maintain its current position, even after changing the transform origin? I am looking for a way to be able to change an element's transform origin while having it not move at all afterwards.
Basically, I'm looking for a way such that I can change the transform origin, but the div would be visually unchanged. I assume this involves some sort of translation in the rotate Javascript function, but I'm unsure of the exact calculations required to achieve such an effect.
The following seems to work:
function setRectangleOrigin(elem, newOrigin) {
const compStyle = window.getComputedStyle(elem);
const prevML = parseInt(compStyle.marginLeft);
const prevMT = parseInt(compStyle.marginTop);
const r1 = elem.getBoundingClientRect();
elem.style.transformOrigin = newOrigin;
const r2 = elem.getBoundingClientRect();
elem.style.marginLeft = prevML + (r1.x - r2.x);
elem.style.marginTop = prevMT + (r1.y - r2.y);
}
Call it like this:
setRectangleOrigin(document.querySelector(".elem"), "top left");
It takes the margin left and margin top of the current rectangle and then calculates its bounding client rect. It then applies the change to the transformation origin and then immediately gets the new bounding client rect.
Then it's a matter of simply transforming the margin left via the change in position.

Why might my jQuery only be working when I have an alert placed in front of the code?

This question is also written in alarming length, because I thought it might be a good teaching moment for other beginners as well.
The goal is to create som artsie-fartsie corner markers around an image, here is how it ought to look:
To achieve this, I first have a bounding/all encompasing div, then 2 empty divs, then the image. The bounding div is styled with some artsie-fartsie box-shadowing and padding, the 2 empty divs are to act as masks over the bounding div and under the image; i.e.:
It is noteworthy to mention that the image height is variable; where is where the difficulty originally stems from.
I originally attempted this 'masking' without the 2 empty divs, using CSS pseudo-elements :before& :after. Solving it this way is preferred, a little lighter and cleaner in my eyes, but using %'s on vertical margins is wonky. The 'vertical-cross mask' is easily acheivable. Here is some CSS, works without fault:
.vert-review-image-cross-block {
background: white;
position: absolute;
width: 70%;
height: calc(100% + 12px);
left: 50%;
margin-left: -35%;
top: -6px;
}
However, do the same for the 'horizontal' masking box does not work. Using % in a margin-top attribute does not work because for a reason that exceeds my intellect, CSS doesn't support this and calculates % against the width. Ergo the following CSS does not properly center the masking box on the 'y' axis:
.horiz-review-image-cross-block {
background: white;
position: absolute;
height: 70%;
width: calc(100% + 12px);
top: 0;
left: -6px;
margin-top: 15%;
}
The height is rendered properly, as 15% of the bounding box's height. But again, using % in margins only uses the width. My solution was then to use JS(jQuery) to manipulate the DOM - take away the margin-top in the CSS and add it with JS. This also supports the need for empty divs, as JS cannot affect pseudo elements. Below, in theory, ought to work fine. It's a tad on the verbose side, I have not attempted any refactoring because it's no behaving properly (called in a document.ready() function):
function reviewImageHorizMaskMargin() {
let reviewMediaImageBoxHeight = $(".review-media-image-box").height();
$(".horiz-review-image-cross-block").css({"margin-top": (reviewMediaImageBoxHeight + 10) * 0.15 + "px"});
}
reviewImageHorizMaskMargin();
But it wasn't working, the applied margin was tiny. So I added a bunch of console.logs to see what's up:
function reviewImageHorizMaskMargin() {
console.log("$('.review-media-image-box').height()[1]: " + $(".review-media-image-box").height());
let reviewMediaImageBoxHeight = $(".review-media-image-box").height();
console.log("reviewMediaImageBoxHeight: " + reviewMediaImageBoxHeight);
console.log("$('.review-media-image-box').height()[2]: " + $(".review-media-image-box").height());
$(".horiz-review-image-cross-block").css({"margin-top": (reviewMediaImageBoxHeight + 10) * 0.15 + "px"});
console.log("$('.review-media-image-box').height()[3]: " + $(".review-media-image-box").height());
}
reviewImageHorizMaskMargin();
The output was buggy as expected:
$('.review-media-image-box').height()[1]: 22
reviewMediaImageBoxHeight: 22
$('.review-media-image-box').height()[2]: 22
$('.review-media-image-box').height()[3]: 22
Then I added an alert, and something magical happend:
...
console.log("$('.review-media-image-box')[1]: " + $(".review-media-image-box").height());
alert("$('.review-media-image-box')[1]: " + $(".review-media-image-box").height());
let reviewMediaImageBoxHeight = $(".review-media-image-box").height();
...
The alert was what I expected, the console output... not so much:
$('.review-media-image-box').height()[1]: 22
reviewMediaImageBoxHeight: 234
$('.review-media-image-box').height()[2]: 234
$('.review-media-image-box').height()[3]: 234
So how is it that the alert function 'sparks' the height to then be correct and thereby the margin to be rendered correctly?

Render div content in fullhd then proportional scale

TV shows slides, that holds HTML inside. TV's resolution is FullHD (1920x1080).
When editing the slide I want to able to know, how slide will exactly be shown on TV. Although I have a FullHD monitor, I've never worked in the browser in fullscreen mode. Other people, which potentially be working with slides, want to see slides as is too.
Using another word, I need to render 1920x1080 div, then proportionally scale it to fit client's browser. How can be this done using CSS or JS, or jQuery?
Edit: I do NOT need to proportional manipulate the image. I need to see how page will look on FullHD resolution regardless of client's viewport resolution
UPDATED!! Here is the demo: https://jsfiddle.net/8jxk0atm/4/
Old resize 1920x1080 aspect ratio demo: https://jsfiddle.net/8jxk0atm/2/
You can create the div spec with 1920x1080. And put this
// screen zoom out for checking
document.body.style.zoom="40%"
on top of your js code.
It will zoom out your document so you can see what it will look on 1920x1080 div.
HTML
<div id="fullscreen"></div>
CSS
html,
body {
margin: 0;
padding: 0;
}
#fullscreen {
width: 1920px;
height: 1080px;
background: green;
color: #fff;
}
JS
// screen zoom out for checking
document.body.style.zoom="40%"
makeFullHD();
function makeFullHD() {
var value = $(window).outerWidth();
value *= 1;
var valueHeight = Math.round((value / 16) * 9);
$('#vidHeight').text(valueHeight);
$('#videoBox').css('width', value + 'px').css('height', valueHeight + 'px');
$('#videoPlayer').css('width', value + 'px');
$('#fullscreen').css({
width: value,
height: valueHeight
});
// test
$('#fullscreen').text('Width:' + value + '\n' + 'Height:' + valueHeight);
}
$(window).resize(function() {
makeFullHD();
});

how to achieve rotating background on scroll

folks I want to make a demo design of this and I got confused how to achieve this. should I go for parallax scrolling or should I prefer skrollr or scrollmagic or just simple css with few jquery code? suggest the simplest way to achieve this.
Thanks :)
Here is working example;
Html
<div class="rotate"></div>
Css
body{
height: 1000px;
background: yellow;
}
.rotate{
background: url("http://i.imgur.com/zZ3fMuh.png");
width: 101px;
height: 102px;
position: fixed;
}
Js
$(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)";
$(".rotate").css({
"-webkit-transform": rotationStr,
"-moz-transform": rotationStr,
"transform": rotationStr
});
});
})
In this particular case they used CSS with the help of JavaScript but the part what you are watching at is CSS (really fluent) and it get executed my an scroll handler.
In this specific case they used the transform: translate3d() property to rotate the yellow background.
If you want to rotate the background when scrolling, look this: https://codepen.io/sarkiroka/pen/gByRmd
In nutshell it uses the sidebar elements for this effect. This elements has :before property with background setting, and a little javascript calculate the rotating degree from the scrollTop. And this javascript overwrite the defined css rule transform property.

Moving Background Image diagonally across the screen

I'm new here, so I can't comment/follow-up yet on another question that PARTIALLY provided an answer
for what I'm trying to achieve.
On this question here [Moving Background image in a loop from left to right the fantastic and very detailed answer by Jack Pattishall Jr lets me set the page background to scroll either vertically OR horizontally.
Is there any way to combine the directional code, so that the page background scrolls diagonally
(i.e. bottom left to top right)?
I've been "mutilating" Jack's code for days now, but can't figure out how to make the background scroll in 2 directions simultaneously. :-(
http://jsfiddle.net/f5WjJ/2/
updates the fiddle from Jack Pattishall Jr to update both x AND y parameters. Also set the repeat CSS to both x AND y as well.
$(function(){
var x = 0;
var y = 0;//here
setInterval(function(){
x+=1;
y-=1;//here
$('body').css('background-position', x + 'px ' + y + 'px');//here too
}, 10);
})
background-repeat: repeat;/*and also here*/
Starting from the example mentioned above, here are my changes:
html, body { height: 100%; width: 100%;}
body {
background-image: url('http://coloradoellie.files.wordpress.com/2013/10/25280-ginger-kitten-leaping-with-arms-outstretched-white-background.jpg?w=300&h=222');
background-repeat: repeat-x repeat-y; // this line could be removed entirely
}
$(function(){
var x = 0;
var y = 0;
setInterval(function(){
x+=1;
y-=1;
$('body').css('background-position', x + 'px ' + y + 'px');
}, 10);
})
Brief description of changes:
Add repeat-y to background-repeat or remove the line (we have replicated the default behavior)
Instantiate and initialize a y-position variable
Move additively on the x-axis and negatively on the y-axis to get the background to move in the desired direction
Edit the $('body') css to include the new non-static y-position
Thanks for the advice, Joseph Neathawk

Categories

Resources