I am trying to change "transform" css property of element, using jQuery:
myBlock.css('-webkit-transform', 'rotate(' + angle + 'deg)');
myBlock.css('-moz-transform', 'rotate(' + angle + 'deg)');
myBlock.css('-ms-transform', 'rotate(' + angle + 'deg)');
myBlock.css('-o-transform', 'rotate(' + angle + 'deg)');
myBlock.css('transform', 'rotate(' + angle + 'deg)');
I want to see all of these properties applied to element, but the result is only
transform: rotate(45ged);
I tried JavaScript style, but it does not help too:
myBlock.style.WebkitTransform = "rotate(" + angle + "deg)";
Applied style is the same, as in previous example.
I found information, that modern jQuery versions (from 1.8) remove prefixes automatically. But why JS-style removes vendor properties?
To write all of these in one "attr('style', 'properties')" string is not a solution, because in this case it removes existing styles.
So the question is: how to apply all transform properties, using JS or jQuery?
Thanks for any help.
Edit: the goal is to have prefixed properties in saved html after executing JS command, not just to execute JS command and rotate div on angle's value.
Perhaps you could first retrieve the style attributes, append your own, and then set it again on the element.
var value = element.getAttribute('style');
value += 'your new style attributes';
element.setAttribute('style', value);
So, I have not found any good solution, except to modify "style" string. Here is it:
myBlock.css('transform', 'rotate(' + angle + 'deg)');
// Fix for old android versions:
var blockStyle = myBlock.attr('style');
if (blockStyle.indexOf('-webkit-transform') === -1) {
blockStyle += " -webkit-transform: rotate(" + angle + "deg);";
}
myBlock.attr('style', blockStyle);
The first line of code overwrites all transform properties, including prefixed. After its execution there will be no -webkit-transform part in style string. Then we add it.
In case of there still will be -webkit-transform in style string somehow after the first command (for me it never happen in modern Chrome, Firefox and Edge), I have else statement, a little bit ugly, but it works.
var blockStyle = myBlock.attr('style');
if (blockStyle.indexOf('-webkit-transform') === -1) {
blockStyle += " -webkit-transform: rotate(" + angle + "deg);";
} else {
var blockStyleArrayOriginal = blockStyle.split('-webkit-transform: rotate(');
blockStyle = blockStyleArrayOriginal[0].trim() + " -webkit-transform: rotate(" + angle + blockStyleArrayOriginal[1].substring(blockStyleArrayOriginal[1].indexOf('deg)'));
}
myBlock.attr('style', blockStyle);
Related
I have this SVG header that, on screen scroll, its parts move differently. For this, I am using a script like the following:
let menu = document.getElementById('main-menu');
let lua = document.getElementById('lua');
window.addEventListener('scroll', function(){
let value = window.scrollY;
menu.style.marginTop = value * 0.45 + 'px'; // working just fine
lua.style.transform = "translateY(" + value * 0.25 + ")"; // don't know how to make this work
OBS: I need to use the transform: translate because this SVG element, for some reason, can't be moved with margin or top/left, only translate.
The menu.style work just fine, but on the lua.style case I'm struggling cause I don't know how to write on the JS a CSS such as transform: translateY that merges a child property (translate) inside another property (transform).
I've tried to write the lua.style.transform = "translateY(" + value * 0.25 + ")"; in many different ways, like:
lua.style.transform = value + "translateY(" * 0.25 + ")";
// or
lua.style.translate = value * 0.45 + 'px';
// or
lua.style.translate = value * 0.45;
// or
lua.style.translate = (0,value * 0.45);
but still can't make it work. How can I write it correctly?
DONE! I used the template literal that Dane Landry explained in the comments. Thanks man.
The code:
lua.style.transform = ` translateY(${value * 0.25}px ) `;
And also thanks kmoser for reminding me translate demans a unit of measurement. It does.
I'm trying to add css from my controller because I need to pass some data that I calculate in it, but I don't know if it's possible, I can only find the syntax with javascript but spaui5 doesn't support it. What I'm trying to do is the following:
var horaHand = that.getView().byId("horaHand");
var minutoHand = that.getView().byId("minutoHand");
var segundoHand = that.getView().byId("segundoHand");
var manillahora = hora + minuto/12;
horaHand.css("transform", "rotate(" + manillahora + "deg)");
minutoHand.css("transform", "rotate(" + minuto + "deg)");
segundoHand.css("transform", "rotate(" + segundo + "deg)");
but it doesn't work. Is there any way I can apply this css?
The original javascript code I'm trying is this:
const hourHand = document.querySelector('#hourHand');
const minuteHand = document.querySelector('#minuteHand');
const secondHand = document.querySelector('#secondHand');
hourHand.style.transform = `rotateZ(${(hours)+(minutes/12)}deg)`;
minuteHand.style.transform = `rotateZ(${minutes}deg)`;
secondHand.style.transform = `rotateZ(${seconds}deg)`;
or this
$('.hour-hand').css({
'transform': `rotate(${hourDegrees}deg)`
});
$('.minute-hand').css({
'transform': `rotate(${minuteDegrees}deg)`
});
$('.second-hand').css({
'transform': `rotate(${secondDegrees}deg)`
});
I solved the problem like this:
$(".hora").css("transform", "rotate(" + hourDegrees + "deg)");
$(".minuto").css("transform", "rotate(" + minuteDegrees + "deg)");
$(".segundo").css("transform", "rotate(" + secondDegrees + "deg)");
but as everybody know, SAPUI5 css only works if you put !important, because of this the code above didn't work. Do you know how can I put put !important in the code in the controller? I tried like this: $(".hora").css("transform", "rotate(" + hourDegrees + "deg) !important"); but doesn't work.
I need help showing/hiding text on a button click (specifically an arrow). I have a block of text that I have hidden and I need to slide it down in a time consistent with the arrow rotating 180 degrees. I also want it to do this only for the post above the arrow that was clicked. The solution I have come up with in this fiddle has many problems.
Here is the code:
$(function () {
var angle = -180,
height = "100%";
$(".down-arrow").click(function () {
$(".down-arrow").css({
'-webkit-transform': 'rotate(' + angle + 'deg)',
'-moz-transform': 'rotate(' + angle + 'deg)',
'-o-transform': 'rotate(' + angle + 'deg)',
'-ms-transform': 'rotate(' + angle + 'deg)',
});
$(".blog-post").animate({
'height' : height
});
angle -= 180;
height = "50px";
});
});
And these are the issues I am having:
It slides down way too fast
Once it slides back up it won't slide down again.
It does it for every post
This would be more dynamic and clean to use:
First we will take height's of all the .blog-post div's in an array.
Now making height: 50px of the div, after once we know actual height of all the div's. Which will helpful in making div smooth slide as we know height's.
Next on click of arrow class, we will toggle class which holds transform:rotate properties. Along with that we would check corresponding .blog-post div's height. So if it is more than 50px we would make it 50px, else we would take it's actual height from array and give to it.
Here is the JS/JQuery Code:
var totalNum = $('.blog-post').length; // Counting number of .blog-post div on page.
var i, myArray = [];
for (i = 0; i < totalNum; i++) {
var curHeight = $('.blog-post:eq(' + i + ')').outerHeight();
myArray.push(curHeight);
}
$('.blog-post').css('height', '50px');
$('.down-arrow').click(function () {
$(this).toggleClass('invert');
var index = $('.down-arrow').index(this);
var heightCheck = $('.blog-post:eq(' + index + ')').outerHeight();
if (heightCheck < 51) {
$('.blog-post:eq(' + index + ')').css('height', myArray[index] + 'px');
} else {
$('.blog-post:eq(' + index + ')').css('height', '50px');
}
});
Working : Fiddle
If you still do not understand feel free to ask.
I guess you should convert the 100% to pixels (with $(this).parent().innerHeight() or something like that, then it works well.
You should build some sort of toggle: keep track of which blog-post/arrow is up and which one is down (flag the blog posts or the arrows with some sort of class) and based on that, you should let it slide up or down.
Of course, you're referring to the post with a css selector. You should use a combination of $(this), .next() and .prev() functions in order to get the right post(s).
"It slides down way too fast"
Just set an animation duration. See the jquery.animate() documentation.
It seems that jquery is pretty buggy when it comes to animating using percentages. http://bugs.jquery.com/ticket/10669 http://bugs.jquery.com/ticket/9505 Try using pixels instead of percentage http://jsfiddle.net/8obybt1d/1/
"Once it slides back up it won't slide down again."
Because you are not changing the value of height back to hundred%
A rough piece of code:
if (height == "50px") {
height = "100%";
}
else {
height == "50px"
}
"It does it for every post"
Try using the 'this' keyword.
To solve point 2:
$(".blog-post").animate({
...
height = (height === "50px") ? height = "100%": height = "50px";
});
How can I rotate a marker in leaflet? I will have a lot of markers, all with a rotation angle.
I've tried this solution from runanet/coomsie at Leaflet on GitHub, but nothing happens with my marker:
L.Marker.RotatedMarker= L.Marker.extend({
_reset: function() {
var pos = this._map.latLngToLayerPoint(this._latlng).round();
L.DomUtil.setPosition(this._icon, pos);
if (this._shadow) {
L.DomUtil.setPosition(this._shadow, pos);
}
if (this.options.iconAngle) {
this._icon.style.WebkitTransform = this._icon.style.WebkitTransform + ' rotate(' + this.options.iconAngle + 'deg)';
this._icon.style.MozTransform = 'rotate(' + this.options.iconAngle + 'deg)';
this._icon.style.MsTransform = 'rotate(' + this.options.iconAngle + 'deg)';
this._icon.style.OTransform = 'rotate(' + this.options.iconAngle + 'deg)';
}
this._icon.style.zIndex = pos.y;
},
setIconAngle: function (iconAngle) {
if (this._map) {
this._removeIcon();
}
this.options.iconAngle = iconAngle;
if (this._map) {
this._initIcon();
this._reset();
}
}
});
var rotated = new L.Marker.RotatedMarker([63.42, 10.39]);
rotated.setIconAngle(90);
rotated.addTo(map);
Any other ideas or solutions? (Testing with Firefox 16 on Windows.)
Running the code as it is, the icon will disappear when you try to rotate it in Firefox (try rotating on a mouseclick instead of on load and you will see that the icon appears before you try to rotate it), but I'm willing to bet it will work (the first time) in a webkit browser. The reason is the transform lines:
this._icon.style.WebkitTransform = this._icon.style.WebkitTransform + ' rotate(' + this.options.iconAngle + 'deg)';
this._icon.style.MozTransform = 'rotate(' + this.options.iconAngle + 'deg)';
Firefox also uses CSS transforms to position icons, so before rotation it will have Moztransform will have a value of for example "translate(956px, 111px)". The way the code is now, it will replace that with simply "rotate(90deg)" and Firefox won't know where to place the icon.
You want Moztransform to have a value of "translate(956px, 111px) rotate(90deg)", so if you use this code it will work the first time, like in webkit.
this._icon.style.MozTransform = this._icon.style.MozTransform + ' rotate(' + this.options.iconAngle + 'deg)';
However, it will break on the next rotate, so you really need to set both the translation and rotation in one go, like this:
this._icon.style.MozTransform = L.DomUtil.getTranslateString(pos) + ' rotate(' + this.options.iconAngle + 'deg)';
Then you can get rid of the L.DomUtil.setPosition(this._icon, pos); at the start.
This solution is by far the easiest: https://github.com/bbecquet/Leaflet.RotatedMarker
Note: it only modifies the existing marker, allowing two more options (rotationAngle and rotationOrigin).
The solution works very well. As per the GitHub page, a usage example:
L.marker([48.8631169, 2.3708919], {
rotationAngle: 45
}).addTo(map);
What works very well for me is adding a data-rotate="[angle]" attribute to each marker. This allows you to call the following JQuery statement on each refresh when necessary:
$('.your-marker-class').each(function () {
var deg = $(this).data('rotate') || 0;
var rotate = 'rotate(' + $(this).data('rotate') + 'deg) scale(0.5,0.5)';
$(this).css({
'-webkit-transform': rotate,
'-moz-transform': rotate,
'-o-transform': rotate,
'-ms-transform': rotate,
'transform': rotate
});
});
Works very fast and with hundreds/thousands of markers. Found this method in some other post somewhere on the internets but seemed right to share here also.
If you're using react-leaflet, I built upon this idea (https://github.com/bbecquet/Leaflet.RotatedMarker) to create a React component that extends Marker and accepts both rotation and rotationOrigin as a prop.
// Libs
import L from 'leaflet'
// Components
import { ExtendableMarker } from 'react-leaflet-extendable'
// HOCS
import { withLeaflet } from 'react-leaflet'
const proto_setPos = L.Marker.prototype._setPos
const LeafletMarker = L.Marker.extend({
_setPos(pos: [number, number]) {
proto_setPos.call(this, pos)
this._setRotation(this.options.rotation)
},
_setRotation(rotation: number | null | undefined) {
if (typeof rotation === 'number') {
this._icon.style[L.DomUtil.TRANSFORM + 'Origin'] = this.options.rotationOrigin || 'center'
const transform = this._icon.style[L.DomUtil.TRANSFORM] + ` rotate(${rotation}deg)`
this._icon.style[L.DomUtil.TRANSFORM] = transform
}
},
})
const createRotatedMarker = (pos: [number, number], options: any) => {
return new LeafletMarker(pos, options)
}
class RotatedMarker extends ExtendableMarker {
public createLeafletElement() {
return createRotatedMarker(this.props.position, { ...this.props })
}
}
export default withLeaflet(RotatedMarker)
Something I've wanted to learn for quite a time now, but haven't been able to figure out.
http://jsfiddle.net/Mobilpadde/Xt7ag/
Then you move the mouse, it follows, which is the easy part, but I want to rotate too, like always look in the direction of the mouse, but not so static, more like, if you move your mouse up, it should kinda rotate first, and then you move the mouse further away, it should begin to follow again (If you know what I mean).
Is that something simple to do, or 3k lines? (Or maybe a jQuery plugin?)
Hiya I got it something more closer by using an old post of mine : demo http://jsfiddle.net/Z3pGQ/3/
I am still working, will flick you more smoother version or if you can improve before me:
Old post: Rotating an element based on cursor position in a separate element
Hope it helps, I am trying to make it smoother now, cheers
Sample code
$(document).ready(function() {
$(document).mousemove(function(e) {
$(".firefly").css({
"top": (e.pageY * 2) + "px",
"left": (e.pageX * 2 + 130) + "px"
});
})
})
var img = $(".firefly");
if (img.length > 0) {
var offset = img.offset();
function mouse(evt) {
var center_x = (offset.left) + (img.width() / 2);
var center_y = (offset.top) + (img.height() / 2);
var mouse_x = evt.pageX;
var mouse_y = evt.pageY;
var radians = Math.atan2(mouse_x - center_x, mouse_y - center_y);
var degree = (radians * (180 / Math.PI) * -1) + 90;
img.css('-moz-transform', 'rotate(' + degree + 'deg)');
img.css('-webkit-transform', 'rotate(' + degree + 'deg)');
img.css('-o-transform', 'rotate(' + degree + 'deg)');
img.css('-ms-transform', 'rotate(' + degree + 'deg)');
}
$(document).mousemove(mouse);
}
Image
This is going to involve a lot more math than I want to do right now, but you can apply rotations with css easily. Here are the properties for mozilla and webkit, you can see the rest of the (IE,Opera...) at this page. Here is your function with a 120deg rotation applied. You will still need to calculate the proper rotation, and adjust the left and top accordingly.
$(document).mousemove(function(e){
$(".firefly").css({
"top":(e.pageY*2)+"px",
"left":(e.pageX*2+130)+"px",
"-moz-transform": "rotate(120deg)",
"-webkit-transform": "rotate(120deg)"});
})
There is a jQuery plugin for that http://pixelscommander.com/en/iphone-development/rotate-html-elements-with-mouse/