-webkit-transform not working in JavaScript rotation animation(no JQuery) - javascript

I made a animation function for a simple game I am making, the animation rotates some text 360degrees 4 times, to give it the appearance that the text is spinning. I looked for similar issues to the one I'm experiencing, but the suggestions did not solve my problem. The animation method is part of my view-object:
rotateText : function(deg, message) {
this.gameState.innerHTML = message;
var animationStepsLeft = this.STEPS;
requestAnimationFrame(setStyle);
function setStyle() {
if(animationStepsLeft > 0) {
Perfection.view.gameState.style =
"-ms-transform: rotate(" + deg + "deg);" +
"-webkit-transform: rotate(" + deg + "deg);" +
"-moz-tranfsform: rotate(" + deg + "deg);" +
"transform: rotate(" + deg + "deg);";
deg += 28.8;
console.log("Rotated");
animationStepsLeft--;
requestAnimationFrame(setStyle);
};
};
},
The "gameState" is a paragraph element in HTML, which is a property of the view object. The method is supposed to take a starting point for the degrees (0) and the message you want to spin - is passed as a string. The amount of steps it's executing is 50, and each time the animation is called the text is rotated 28.8 degrees. My issue is that the animation works flawlessly in Firefox but does not seem to work in webkit based browsers (It's not working in Chrome or Safari). I should mention that the method is being called, as I've attached a console.log in the attempt to debug, and it's being logged 50 times, and the text appears on the screen, but does not rotate. I read in a similar post that in webkit browsers the elements need to be displayed as an inline-block, so I had my CSS styles set as:
#game-state {
display: inline-block;
position: absolute;
margin-left: auto;
margin-right: auto;
margin-top: 200px;
z-index: 2;
font-family: "Tahoma", Geneva, sans-serif;
text-shadow: -3px 0 black, 0 3px black, 3px 0 black, 0 -3px black;
font-size: 100px;
color: rgb(213,40,8);
}
But it is still not working!
Can anyone help me pls!

I suggest that you should open console and see what inside element.style. Style is a set of properties. EG: style.height, style.visible... not style="".
You should change your code to <element>.style.transform='rotate(' + deg + 'deg)'. For -ms-transform you can try to use .style['-ms-transform'].
Using raw javascript then you must detect your browser for supported style.

Related

setProperty("left",...) on absolute div slow in parallax

I want to build a sidescrolling parallax effect with 3 different overlaying pictures that move at different speeds, my code for this is the following:
<div class="parallax-wrapper">
<div class="parallax1 parallax"></div>
<div class="parallax2 parallax"></div>
<div class="parallax3 parallax"></div>
</div>
.parallax-wrapper {
width: 100%;
height: 100%;
background-color: black;
}
.parallax {
position: fixed;
display: inline-block;
width: 500%;
height: 100%;
left: 0;
background-size: auto 100%;
}
.parallax1 {
background-image: url("../assets/Parallax/Parallax1.svg");
}
.parallax2 {
background-image: url("../assets/Parallax/Parallax2.svg");
}
.parallax3 {
background-image: url("../assets/Parallax/Parallax3.svg");
}
and this function that is called on scroll:
function updateScroll(scrollDest){
parallax1.style.setProperty("left", "-" + (scrollDest * 0.3) + "px")
parallax2.style.setProperty("left", "-" + (scrollDest * 0.2) + "px")
parallax3.style.setProperty("left", "-" + (scrollDest * 0.1) + "px")
}
I have done this differently before which worked but had little browser support so I changed it to this method which I thought was very lightweight but sadly it is very laggy on mobile and also not very smooth on my desktop PC, why is this method so slow and how to improve it?
I guess you probably just added event listener to window on scroll, that causes calling updateScroll on every scroll event. I'd suggest using throttling and debouncing, to reduce amount of events (Great example you can find on other stack question "Simple throttle in JavaScript".
After reducing the amount of events it'll be a little weird, so I'd suggest adding also transition on left like this:
.parallax {
transition: left .2s;
}

Contenteditable height transition: animate after adding (shift+enter) and removing a line of text

It works so far on using the contenteditable attribute on the <div> tag with the autogrow feature of a textbox. Also the height transition of it. It all works good, except for one thing, deleting characters, to be specific, a line, will not animate its height, unlike adding new lines. I have still a little knowledge on CSS.
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
<div class="autogrow" contenteditable="true"></div>
When I press Shift + Enter, it doesn't animate either, it does well though while pressing Enter. Just the removing of lines and the Shift + Enter key combination while entering a new line is the problem.
How to make it work? Can it be done using pure CSS? Or adding a javascript function for it?
To avoid these issues, I personally use a solution not based on pure CSS animations / transitions which I found always have problems. For example, in your CSS implementation, there is a bounce back effect if using the Enter too fast (you can slow the animation down to see it better).
Moreover, new lines handling is different between browsers, some will add <div><br></div>, some versions of IE add only <br>, etc.
I've never been able to fix all these problems or found an implementation fixing all of these so I decided to not modify at all the behavior of the contenteditable, let the browser do is magic which works and instead, react to what's happening.
We don't even have to worry about keys events like Shift + Enter or events like deletion, etc., all of these are natively handled by the navigator.
I choose instead to use 2 elements: one for the actual contenteditable and one for the styling of my contenteditable which will be the one having height animations / transitions based on the actual height of the contenteditable.
To do that, I'm monitoring every events that can change the height of a contenteditable and if the height of my styling element is not the same, I'm animating the styling element.
var kAnimationSpeed = 125;
var kPadding = 10;
$('div[contenteditable]').on('blur keyup paste input', function() {
var styleElement = $(this).prev();
var editorHeight = $(this).height();
var styleElementHeight = styleElement.height();
if (editorHeight !== styleElementHeight - kPadding * 2) {
styleElement.stop().animate({ height: editorHeight + kPadding * 2 }, kAnimationSpeed);
}
});
.autogrowWrapper {
position: relative;
}
.autogrow {
border: 1px solid rgb(0, 0, 0);
height: 40px; /* line-height + 2 * padding */
}
div[contenteditable] {
outline: none;
line-height : 20px;
position: absolute;
top: 10px; /* padding */
left: 10px; /* padding */
right: 10px; /* padding */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="autogrowWrapper">
<div class="autogrow"></div>
<div contenteditable="true"></div>
</div>
It's kinda hacky, but it works.
First, modify your CSS
.autogrow {
border: 1px solid rgb( 0, 0, 0 );
padding: 10px;
}
#keyframes line_insert {
from {
height: 0px;
}
to {
height: 20px;
}
}
.autogrow[contenteditable] > div {
animation-duration: 250ms;
animation-name: line_insert;
}
.autogrow[contenteditable] {
overflow: hidden;
line-height: 20px;
}
Then add this jQuery that detects Shift + Enter events and appends a div whenever they occur
$(".autogrow").keydown(function(e){
if (e.keyCode == 13 && e.shiftKey || e.keyCode == 13)
{
$(this).animate({height: $(this).height()+20},200);
$(this).append('<div><br></div>');
}
});
And that should work.
Check fiddle https://jsfiddle.net/wx38rz5L/582/

Preserving and adding new transform on hover (CSS/LESS)

To make it simple, I have a div that I rotate by default with a JS code. But then I want to add a :hover class, so that it translates when hovering over it. The problem is, that either the new transform does not apply, or the old is not preserved.
How can I make it work? Btw, I am using LESS, so if there's a solution with LESS, would be happy to hear it.
P.S. The angle is being generated according to the number of siblings in JS. Maybe I would be able to do a rotation with LESS and then do a :hover there?
document.getElementById("box").style.transform = "rotate(" + 40 + "deg)";
#box {
width: 50px;
height: 50px;
background-color: red;
transition: all 0.5s ease-in;
}
#box:hover {
background-color: blue;
transform: translate(50px) !important;
}
<div id="box">
</div>
you cannot achieve the desired result using CSS/LESS. You have to use JavaScript to generate dynamic styles. A script similar to below can do the task on your hand:
var dynamic_styles = '';
var counter = 1;
$('.box').each(function() {
$(this).attr('data-num', counter);
dynamic_styles += '.box[data-num="' + counter + '"] {transform: rotate(40deg);}';
dynamic_styles += '.box[data-num="' + counter + '"]:hover {transform: rotate(40deg) translate(50px);}';
counter++;
});
$('head').append('<style>' + dynamic_styles + '</style>');
Please check the codepen here:
http://codepen.io/anon/pen/LGzXEM
P.S. You can change the rotation 40deg with your dynamically calculated values.

Strange Progress Bar Behavior offsetwidth

I started developing a simple progress bar using vanilla JavaScript. As far as grabbing a width set in CSS the only way I found with JS is to use .offsetWidth - The following is the code for the functionality demo I was beginning to setup. The fiddle link is at the bottom of the question.
HTML:
<section id="box"></section>
<p>
<section id="box2"></section>
CSS:
#box, #box2 {
height: 10px;
width: 5px;
background-color: lightBlue;
}
#box2 {
width: 4px;
}
JavaScript (onload) :
var savedwidth = document.getElementById("box").offsetWidth;
alert("box 1 width " + savedwidth);
savedwidth = document.getElementById("box2").offsetWidth;
alert("box 2 width " + savedwidth);
While testing it out to see if it grabbed the property accurately I noticed that when the width was set to 5px it returned 6px. Everything else seems fine.
4px = 4px, 6px = 6px.
I was curious if anyone knew why that happened? It's minimal enough where it won't affect what I'm trying to do seemingly, but the more you know the better off you'll be.
FIDDLE : http://jsfiddle.net/5yk9e5du/

Resize and repositon div using javascript

I'm trying to do a simple resize and reposition of a div element that shows a ajax loading image. The content it loads can change size, so I want the div element to resize to be the size of the parent, which in this case is a table dimension with the id "thEngineCategories".
function resize_divProgress() {
var control = document.getElementById('thEngineCategories');
var div = document.getElementById('divProgress');
div.style.left = control.offsetLeft + 'px';
div.style.top = control.offsetTop + 'px';
div.style.width = control.offsetWidth + 'px';
div.style.height = control.offsetHeight + 'px';
}
The following is the javascript I have and it errors on
div.style.left = control.offsetLeft + 'px';
saying "div.style is undefined". Whats wrong here?
The div in html is as follows:
<div class="overlay" id="divProgress">
The js function is called as follows:
<th id="thEngineCategories" onmouseover="resize_divProgress()" >
The CSS is:
.overlay
{
border: black 1px solid;
padding: 5px;
z-index: 100;
width: 300px;
position: absolute;
background-color: #fff;
-moz-opacity: 0.75;
opacity: 0.75;
filter: alpha(opacity=75);
font-family: Tahoma;
font-size: 11px;
font-weight: bold;
text-align: center;
}
Is there a better way to handle what I'm trying to do?
I created a basic test page from the code you provided and couldn't reproduce the problem. This suggests there is something else going on in your page that is causing the behaviour you are seeing.
Could you take your page and pare it down to a minimal case that demonstrates the JavaScript error? You'll find performing this process often will reveal the cause of the error - you'll remove something and it will start working, indicating that something in that removed section of code is the source of the problem :)
div.style.width is not valid property for accessing width of div.
use div.offsetWidth and div.offsetHeight for width and height respectively.

Categories