weird behaviour in css transform:rotate - javascript

i trying to make this item draggable and rotatable.
however if i set transform:rotate(0deg);
i can drag everywhere in the parent container.
but if i set it to 90deg. there are some area became undraggable and it extended out of the parent container as well.
<div id="container">
<div id="myitem"><p>my rotate/drag</p></div>
CSS:
#container{
width:500px;
height:500px;
background:red;
}
#myitem{
width:115px;
height 50px;
background:black;
transform-origin:top left;
transform: rotate("90deg);
-ms-transform-origin:top left;
-ms-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-webkit-transform-origin:top left;
}
look for the example here
click here for sample of the problem
Have solucioned the problem!
If capture $(foo).offset().left when set css scale the value is not equals to real position if use transform-origin: top left;
To fix this replace
$(foo).offset().left by parseInt($(foo).css('left').replace('px',))
but need set
position after run: foo{ top: 0; left: 0; position: absolute; }
:)
The problem is who detect transform-origin and difference of positions when apply an scale(). Calculate by %?

I just running around your question, basically you want a draggable and rotatable with container...
I have done some changes to your fiddle and try to achieve this, http://jsfiddle.net/28WG3/19/
Some changes to the html too:-
<div id="container">
<div id="main"><div id="myitem"><p>my rotate/drag</p></div>
</div>
</div>
Hope this works for you...

Related

Put a vertical slider to the left or right of an html object

I have a canvas that displays video, and I want to bind a range slider to the left or right side of it. CSS is proving to really fight with me on this one. I can deal with stretching or slider values but just binding it to the side of that canvas is what is proving very difficult. Any help is greatly appreciated. If it's any easier to explain with a horizontal slider I will also be binding one to the bottom, may be simpler since I'm not rotating the style of the slider.
HTML:
<div class="centerVideo">
<canvas id="video-canvas" style="width: 1024px; height: 576px"></canvas>
<div style="float: right; position: fixed;">
<form name="verticalForm">
<output name="verticalValue" for="verticalRange" id="verticalLabel" style="font-size:22px;">Tilt: </output>
<span style="font-size:12px;">0</span>
<input type="range" style="transform:rotate(270deg);" name="verticalInput" id="verticalID" value="0" min="-90" max="0" oninput="tilt(this.value)">
<script>
function tilt(val) {
//do stuff
}
</script>
<br>
<span style="font-size:12px;">-90</span>
</form>
</div>
</div>
CSS:
.centerVideo {
margin: 0;
position: absolute;
top: 30%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
Here is a Codepen https://codepen.io/thisisloop/pen/gOaBLjE
I added your Slider to the left of the screen and added a class to the slider div.
Inside this class I added:
position: relative;
right: 15%; //for changing the horizontal position can also use "left:"
bottom: 510px; //for changing the vertical position can also use "top:"
You could do this more cleaner if you used flexbox or grid, here are some nice ressources to learn:
https://css-tricks.com/snippets/css/complete-guide-grid/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
These are essential for making good layouts.
Hope I could help you

Text blurring only on firefox with animation [duplicate]

I just want to skew the parent and skew it back on the child.
Example : HTML
<div class="parent"> <!-- skew(-10deg) -->
<div class="child">Hello</div> <!-- skew(10deg) (skew back) -->
</div>
Example : CSS
.parent {
transform: skew(-10deg);
}
.child {
transform: skew(10deg);
}
Text inside seems ok with Firefox, Safari. But not Chrome and Opera its a bit blurry
I have to use -webkit-backface-visibility: hidden; for reduce box pixelated in Chrome
Firefox :
Chrome :
Firefox vs Chrome :
or zoomed by Photoshop
Live example : http://jsfiddle.net/1tpj1kka/
Any idea ?
NOTE !!! : web-tiki's answer is an another way solution to prevent the problem. But if any answered a real solution to resolved this skew back problem (real fix), I will accept the answer.
The "blurry text" after 2d or 3d transforms with webkit browsers has been discused many times. But in your case, you can apply the transform only on a pseudo element so that your text isn't affected by the skew property.
It will also alow you to use only one tag in your markup :
#import url(https://fonts.googleapis.com/css?family=Oswald);
body{color:#fff;font-weight: bold;font-size:50px;font-family:'Oswald',sans-serif;}
.parent {
width: 300px;
overflow: hidden;
padding-left: 5%;
position:relative;
}
.parent::before {
content :'';
position:absolute;
top:0;left:0;
width:100%; height:100%;
background: rgba(90,190,230,0.9);
transform-origin:0 0;
transform:skew(-10deg);
z-index:-1;
}
<div class="parent">
Hello
</div>
Adding the 'translateZ(0)' before transformations like below forces the gpu to re-render the text and removes blurry-ness on Chrome.
This:
transform: translateZ(0) skew(-10deg);
Not This:
transform: skew(-10deg);
You can try the text-rendering: geometricPrecision CSS property. This will force your text to not be anti-aliased, thus making the blurriness less important.
inp.onchange = function(){
document.querySelector('.child').classList.toggle('geo');
}
#import url(https://fonts.googleapis.com/css?family=Oswald);body{color:#fff;font-weight:bold;font-size:50px;font-family:'Oswald',sans-serif;}
.geo{
text-rendering: geometricPrecision;
}
.parent {
transform: skew(-10deg);
-webkit-backface-visibility: hidden;
width:300px;padding-left:15%;margin-left:-15%;overflow:hidden;
}
.child {
transform: skew(10deg);
width:300px;background: rgba(90, 190, 230, 0.9);padding-left: 5%;padding-right: 15%;
}
<div class="parent"> <!-- skew(-10deg) -->
<div class="child geo">Hello</div> <!-- skew(10deg) (skew back) -->
</div>
<input type="checkbox" id="inp" checked="true"/> geometricPrecision

CSS HTML: Is there workaround for parent scaling and child position:fixed?

So the problem occurs if we have parent element which is scaled and children elements with position:fixed:
.parent {
transform: scale(2);
transform-origin: 0 0 0;
}
.child {
position:fixed;
}
It breaks the child position:fixed caused by scale(2) on the parent element. The problem has been known since 2 years ago. Is there a workaround for this problem?
I really have to use scale on the parent and position:fixed on the children for some reason.
I don't know where you want to position the child element. But I know that in your case the bottom and right attributes to position the child attribute don't work as expected. The top and left propterties do though.
To position the child element in the lower right corner I found the following workaround:
<html>
<head>
<style>
.parent {
transform: scale(2);
transform-origin: 0 0 0;
background-color: blue;
}
.child {
position: fixed;
left: calc(50vw - 100px);
top: calc(50vh - 100px);
background-color: red;
}
</style>
</head>
<body>
<div class="parent">
parent
<div class="child">child</div>
</div>
</body>
</html>
For some reason the viewport of the child gets increased by the scale of the parent. Because of that you have to decrease the viewport by 50% in case of a scaling by the factor of 2.
If this does not help you please let me know where you want to position the child element.

Rotate animation hover but while moving mouse on hover -> cancel

I'm trying to trigger a rotate animation in an SVG on my website. It definetly work but the problem is when i'm moving my mouse when i'm on hover the element it cancels the animation.
So i include an object svg element:
<object type="image/svg+xml" data="branching4.svg" id="branching">
Your browser does not support SVG
</object>
which is a long SVG document but here is stylesheet attached to it:
#rectangle1, #rectangle2, #rectangle3{
perspective: 1500px;
}
#rectangle1.flip .card, #rectangle2.flip .card, #rectangle3.flip .card {
transform: rotateX(180deg);
}
#rectangle1 .card, #rectangle2 .card, #rectangle3 .card{
transform-style:preserve-3d;
transition:1s;
}
#rectangle1 .face, #rectangle2 .face, #rectangle3 .face{
backface-visibility: hidden;
}
#rectangle1 #front1{
transform: rotateX(0deg);
}
#rectangle1 #back1{
transform: rotateX( 180deg );
}
#rectangle2 #front2{
transform: rotateX(0deg);
}
#rectangle2 #back2{
transform: rotateX( 180deg );
}
#rectangle3 #front3{
transform: rotateX(0deg);
}
#rectangle3 #back3{
transform: rotateX( 180deg );
}
#rectangle1.flipped, #rectangle2.flipped, #rectangle3.flipped {
transform: rotateX( 180deg );
}
You can see the svg structure in the jsfiddle
And finally the script:
window.onload=function() {
var svgDoc = $("#branching")[0].contentDocument; // Get the document object for the SVG
$(".st4", svgDoc).css("font-family", "robotolight,Helvetica Neue,Helvetica,Arial,sans-serif");
$("#rectangle1", svgDoc).hover(function(){
$(this, svgDoc).toggleClass("flip");
});
$("#rectangle2", svgDoc).hover(function(){
$(this, svgDoc).toggleClass("flip");
});
$("#rectangle3", svgDoc).hover(function(){
$(this, svgDoc).toggleClass("flip");
});
};
I also tried with CSS, it's the same problem.
Here is a jsfiddle:
https://jsfiddle.net/7f7wjvvt/
1st question:
How can i have a fluid rotate transition when moving the mouse on the element ?
2nd question:
How can i have a Y rotation that stay on the spot and not translate to the left ? Try it in the fiddle
3rd question:
Why the jsfiddle display the svg well in firefox and not in chrome?
Also, perspective doesn't seem to work in chrome ... WHY ?
Any ideas ?
Unfortunately, I think many of the problems you're experiencing are simply the result of bad browser support for (3D) css transforms on svg elements.
Moving the cards <g> elements to their own <svg> inside an ordinary <div>, and applying the interactivity to the div element would make stuff a lot easier.
.card {
display: inline-block;
transform-origin: center;
perspective: 1000px;
background: grey;
}
.card-inner {
width: 100px;
height: 200px;
transition: transform .4s;
}
.card-inner:hover,
.card:hover > .card-inner {
transform: rotateY(180deg);
}
<div class="card">
<div class="card-inner" style="background: yellow">
Add svg card here
</div>
</div>
<div class="card">
<div class="card-inner" style="background: blue">
Add svg card here
</div>
</div>
<div class="card">
<div class="card-inner" style="background: green">
Add svg card here
</div>
</div>
How can i have a fluid rotate transition when moving the mouse on the element ?
Once the card rotates, it easily looses hover. The hover state will be applied to underlying element though. If you make sure this is the card's parent, you can use this css rule for styling:
.card-inner:hover,
.card:hover > .card-inner {
transform: rotateY(180deg);
}
How can i have a Y rotation that stay on the spot and not translate to the left ? Try it in the fiddle
You'll have to use transform-origin, like you tried. It just doesn't work for svg elements...
transform-origin: center;
Why the jsfiddle display the svg well in firefox and not in chrome? Also, perspective doesn't seem to work in chrome ... WHY ?
Like I said, it just isn't supported properly...
Re your first problem with the flip
It looks like the problem is that when the cards spin, they shrink. Then the mouse is no longer over the card and when the card moves around again it re-enters and the mouseenter event fires again. Then the whole process repeats (as long as the mouse is moving).
The solution is to prevent the event from firing again until the animation i complete.
There are several ways to fix this, but here is one solution:
// Flag to keep track of whether rectangle1 is flipping
var flipping1 = false;
$("#rectangle1").mouseenter(function() {
// Only toggle the animation if we aren't already doing so
if (!flipping1) {
// Add the class to start the flip
$(this).toggleClass("flip");
// Set flag to mark that we are flipping
flipping1 = true;
// Then in just over a second, turn the flag off again
setTimeout(function () {
flipping1 = false;
}, 1010);
}
});
Here's a fiddle showing this technique working on just rectangle1.
https://jsfiddle.net/7f7wjvvt/4/
I don't have a complete answer but for your first question I'd suggest replacing the .hover with a .mouseenter trigger, and for the second one just lose the perspective.
Also, I tried prefixing your css but to no avail, seems there's some compatibility issues between the browsers here.

Setting a transform-origin of a CSS3 pseudo 3d object

I am trying to build a "pseudo 3D" CSS3 slideshow to hold the projects for my website.
The code I have for each element is
<div class="projects">
<div class="wrapper">
<section id="widget_sp_image-8" class="widget widget_sp_image">
<h1 class="widget-title">Live Manager</h1>
<div class="widget_sp_image-description">
<p>Lorem ipsum</p>
</div>
</section>
<!-- And so on -->
</div>
</div>
Basically, all each card is set to position: absolute; and I rotate them around 360 degrees width Javascript. I want to rotate it around it itself by 45deg every time an user presses left or right, but I have difficulties setting it's transform origin. I have this as a code:
.projects .wrapper {
width: 470px;
display: block;
margin: 0 auto;
position: relative;
-webkit-transform: translateZ(-700px);
-webkit-transform-style: preserve-3d;
-webkit-transform-origin: 50%;
}
But when the left or right arrows are pressed, the slideshow start rotating awkwardly around its side, so the transform-origin doesn't do the trick.
Here is a link to the codepen project:
http://codepen.io/gbnikolov/pen/qyfzp
2 problem!
first when you translate your wrapper -720px in Z axis, so must translate your origin -720px in Z axis too!
.wrapper {
-webkit-transform-origin: 50% 50% -700px;
}
and second problem is:
wrapper.style.webkitTransform += is wrong! because in every key pressing its value will be duplicated!
currently i fix it, but it's not a good way to rotate it!
see [ THIS ]

Categories

Resources