Bullet Point not moving, only the image is - javascript

I need to animate the points in a bullet list, the bullet list is a div that contains bullet points that are divs.
A bullet point div contains an image and another div which has the bullet point text, the problem is when I try and move a given bullet point div only the image is moved.
I have tried various changes to the .style.position to no avail.
I could not create an account on jsfiddle.net so the following is a working example that moves only the first bullet point:
<html>
<head>
<title>Build Bullets</title>
<body>
<script>
window.setTimeout('initBuildBullets()',100);
function initBuildBullets(){
var bulletPointsDiv = document.createElement('div');
var bName = 'BulletList';
bulletPointsDiv.style.visibility='visible';
bulletPointsDiv.style.position = 'fixed';
bulletPointsDiv.style.display = 'block';
bulletPointsDiv.style.textAlign = 'left';
bulletPointsDiv.id = bName;
document.body.appendChild(bulletPointsDiv);
var bullet_src = 'bullet_level_1.gif';
var bulletText=[];
bulletText[0]='Bullet Point 1';
bulletText[1]='Bullet Point 2';
bulletText[2]='Bullet Point 3';
var x=100;
var y=100;
var h=100;
var w=200;
var lastBot = 0;
var indent = 0;
var imgW = 25;
var hOffset = 5;
for(var i=0;i<bulletText.length;i++){
var bp_id = bName + '_Bullet_Point_' + i;
var bulletPointDiv = document.createElement('div');
bulletPointDiv.id = bp_id;
bulletPointDiv.style.overflow = 'hidden';
bulletPointDiv.style.visibility='visible';
bulletPointDiv.style.position = 'inherit';
bulletPointDiv.style.display = 'inherit';
bulletPointDiv.style.textAlign = 'left';
bulletPointDiv.style.top = (y + lastBot) + 'px';
bulletPointDiv.style.left = (x + indent) + 'px';
var bulletImage = document.createElement('img');
bulletImage.src = bullet_src;
bulletImage.id = bName + '_Bullet_Image_' + i;
var bulletFieldDiv = document.createElement('div');
bulletFieldDiv.id = bName + '_Bullet_Field_' + i;
bulletFieldDiv.style.overflow = 'hidden';
bulletFieldDiv.style.position = 'inherit';
bulletFieldDiv.style.display = 'inherit';
bulletFieldDiv.style.textAlign = 'left';
bulletFieldDiv.style.top = (y + lastBot) + 'px';
bulletFieldDiv.style.left = (x + imgW + indent) + 'px';
bulletFieldDiv.style.width = (w - (imgW + indent)) + 'px';
bulletFieldDiv.innerHTML = bulletText[i];
bulletFieldDiv.style.visibility='visible';
bulletPointDiv.appendChild(bulletImage);
bulletPointDiv.appendChild(bulletFieldDiv);
bulletPointsDiv.appendChild(bulletPointDiv);
lastBot += bulletFieldDiv.offsetHeight + hOffset;
}
window.setTimeout('moveBullets()',100);
}
function moveBullets(){
var bp_id = 'BulletList_Bullet_Point_0';
bulletPointDiv = document.getElementById(bp_id);
bulletPointDiv.style.top = '0px';
bulletPointDiv.style.left = '0px';
}
</script>
</body>
</html>
If I could ask that you copy/paste to test.
The following image is the bullet_level_1.gif

I need to set the style.position to 'relative' and then the top and left needs to account for the image (ONLY), once I do that then all objects within the div will move with the div, e.g.:
...
var bulletImage = document.createElement('img');
bulletImage.src = bullet_src;
var imgW = bulletImage.width + 8;
var bulletFieldDiv = document.createElement('div');
bulletFieldDiv.style.position = 'relative';
bulletFieldDiv.style.top = '-' + (bulletImage.height + 8) + 'px';
bulletFieldDiv.style.left = imgW + 'px';
...
That said, I'm not sure why I need the additional 8px for both the height and width??

Related

Prevent double images in function using Math.random

I have a function that adds random images to my divs that disappear over time and create a mouse trail. My issue is: there are double images.
I'd like to add something that checks if the background url is already located on the page and if that's the case, skips to the next in the array and check it again until until it comes across one that is not there. So like a loop that refreshes every time a 'trail' is being created.
Maybe I am asking for something that won't work? What if all the images are already on the page? I don't really have an answer for it and I also don't have an idea how to solve that problem yet.
For now I tried adding a counter that checks the usedImages and counts them, but it seems to have flaws and I am unsure where to look or how to fix it. Does anyone have any tips on how to do this? Is it even possible?
My fiddle
var bgImages = new Array(
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/schraegluftbild-1024x725.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/pikto-608x1024.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/Jettenhausen-EG-Grundriss-913x1024.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/lageplan-945x1024.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/Jettenhausen-EG-Grundriss-913x1024.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/05/Jettenhauser-Esch-Modell-2-1024x768.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/07/DSCN3481-1024x768.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2019/07/zoom-in-3_ASTOC-1024x683.jpg",
"https://www.studiourbanestrategien.com/wordpress/wp-content/uploads/2016/07/IMG_1345-1024x768.jpg"
);
const numberOfImages = 10;
const timesPerSecond = .1;
var usedImages = {};
var usedImagesCount = 0;
function preloadImages(images) {
for (i = 0; i < images.length; i++) {
let l = document.createElement('link')
l.rel = 'preload'
l.as = 'image'
l.href = images[i]
document.head.appendChild(l);
}
}
function animate(e) {
var image = document.createElement('div');
image.classList.add('trail');
var sizew = 200;
var sizeh = 200;
image.style.transition = '3s ease';
image.style.position = 'fixed';
image.style.top = e.pageY - sizeh / 2 + 'px';
image.style.left = e.pageX - sizew / 2 + 'px';
image.style.width = sizew + 'px';
image.style.height = sizeh + 'px';
var random = Math.floor(Math.random() * (bgImages.length));
if (!usedImages[random]) {
image.style.backgroundImage = "url(" + bgImages[random] + ")";
usedImages[random] = true;
usedImagesCount++;
if (usedImagesCount === bgImages.length) {
usedImagesCount = 0;
usedImages = {};
}
} else {
animate(e);
}
console.log(usedImages);
console.log(usedImagesCount);
image.style.backgroundSize = 'cover';
image.style.pointerEvents = 'none';
image.style.zIndex = 1;
document.body.appendChild(image);
//opacity and blur animations
window.setTimeout(function() {
image.style.opacity = 0;
image.style.filter = 'blur(20px)';
}, 40);
window.setTimeout(function() {
document.body.removeChild(image);
}, 2100);
};
window.onload = function() {
preloadImages(bgImages);
var wait = false;
window.addEventListener('mousemove', function(e) {
if (!wait) {
wait = true;
setTimeout(() => {
wait = false
}, timesPerSecond * 800);
animate(e);
}
});
};

Make a multiple objects with javascript and png

I'm trying to get a spaceship animation scene with a group of comets going down.
//Create a comet div with img attached to it
var cometScene = function(spaceNo){
var b = document.createElement('div');
b.id = 'cometio';
var cometImage = document.createElement('img');
cometImage.setAttribute('src', 'images/comet1.png');
b.appendChild(cometImage);
document.getElementById('wrap').appendChild(b);
}
//Comet move
function cometMove(){
var comet = document.getElementById('cometio');
var pos = 0;
var interval = setInterval(scene, 3);
function scene(){
if (pos === 1000){
clearInterval(interval);
} else {
pos++;
comet.style.top = pos + 'px';
comet.style.left = pos + 'px';
}
}
setInterval(scene, 3)
}
But when I call a function cometScene(3) I'm not getting 3 similar objects. Also how these objects can be allocated across the whole screen as this is just a single div.
function main(){
var w = document.createElement('div');
w.id = 'wrap';
document.querySelector('body').appendChild(w);
astronautScene();
cometScene();
shaceshipScene();
cometMove();
astronautMove();
}
This it what I would do:
Give the comets a class instead of an id, because there can be more of them.
Because there can be multiple use a loop to iterate through them
To give them the ability to move freely, they need to have position:absolute or something similiar
Don't use the same variable for the position of all comets, because they could be in different positions
To get the current position just parse the currect top and left value to a Number
//Create a comet div with img attached to it
var cometScene = function(spaceNo) {
var b = document.createElement('div');
b.className = 'cometio';
var cometImage = document.createElement('img');
cometImage.setAttribute('src', 'images/comet1.png');
b.appendChild(cometImage);
document.getElementById('wrap').appendChild(b);
}
//Comet move
function cometMove() {
var comets = document.getElementsByClassName('cometio');
for (let i = 0; i < comets.length; i++) {
const comet = comets[i];
comet.style.top = "0px";
comet.style.left = "0px";
comet.style.position = "absolute";
var interval = setInterval(scene, 3);
function scene() {
let x = parseInt(comet.style.left);
let y = parseInt(comet.style.top);
if (x === 1000) {
clearInterval(interval);
} else {
comet.style.top = (1 + x) + 'px';
comet.style.left = (1 + y) + 'px';
}
}
}
//setInterval(scene, 3)don't start the interval twice
}
function main() {
var w = document.createElement('div');
w.id = 'wrap';
document.querySelector('body').appendChild(w);
//astronautScene();
cometScene();
//shaceshipScene();
cometMove();
//astronautMove();
}
main();

SVG circles pulse synchronous doesn't work

I want to position one circle svg for each click I do on the object window.
My function works fine but what can I do to make circles pulse synchronous?
window.addEventListener("click",
function(event){
var myBody = document.getElementsByTagName("body")[0];
var circleDiv = document.createElement("div");
circleDiv.innerHTML = "<svg><circle cx='80' cy='80' r='20' stroke='black' fill='white' fill-opacity='0.0' /></svg>";
circleDiv.style.position = "absolute";
circleDiv.style.left = event.x+'px';
circleDiv.style.top = event.y+'px';
var direction = 5;
var radius = 20;
window.setInterval(function()
{
radius = radius + direction;
if(radius<10) direction = 5;
if(radius>50) direction = -5;
circleDiv.firstChild.firstChild.setAttribute("r",radius);
},500);
myBody.appendChild(circleDiv);
}
);
If by 'synchronus' you talk about pusle together you must split your function as is :
var direction = 1;
var radius = 20;
window.addEventListener("click",
function(event){
var myBody = document.getElementsByTagName("body")[0];
var circleDiv = document.createElement("div");
circleDiv.innerHTML = "<svg><circle cx='80' cy='80' r='" + radius + "' stroke='black' fill='white' fill-opacity='0.0' /></svg>";
circleDiv.style.position = "absolute";
circleDiv.style.left = event.x+'px';
circleDiv.style.top = event.y+'px';
myBody.appendChild(circleDiv);
}
);
window.setInterval(function()
{
var circles = document.getElementsByTagName('circle');
radius = radius + direction;
if(radius<10) direction = 1;
if(radius>50) direction = -1;
for(var i = 0; i < circles.length; i++) {
circle = circles[i];
circle.setAttribute("r",radius);
}
},20);
Here the jsFiddle
Hope it helps ;)
As you add the circles capture them in an array circles and have just one timer to update their sizes. Note I added putting your handlers in the jquery document ready function. This is good practise. Try this:
var circles = [];
var radius = 20;
var direction = 5;
jQuery(document).ready(function() {
window.addEventListener("click", function(event){
var myBody = document.getElementsByTagName("body")[0];
var circleDiv = document.createElement("div");
circleDiv.innerHTML = "<svg><circle cx='80' cy='80' r='20' stroke='black' fill='white' fill-opacity='0.0' /></svg>";
circleDiv.style.position = "absolute";
circleDiv.style.left = event.x + 'px';
circleDiv.style.top = event.y + 'px';
circles.push(circleDiv);
myBody.appendChild(circleDiv);
});
window.setInterval(function() {
radius = radius + direction;
if(radius<10) direction = 5;
if(radius>50) direction = -5;
for(var i = 0; i < circles.length; i++){
circles[i].firstChild.firstChild.setAttribute("r",radius);
}
} ,500);
});
You might want to make sure the SVG you create is using the radius value to set the starting size.

Expand the width of an element with a setTimeOut loop

I am trying to create a simple javascript animation that will expand the width of an element from 0px to a specified width. Although this is probably a pretty elementary problem for some, I just can't seem to figure out what I am doing wrong. Instead of the loop running and expanding the div as desired I am only able to expand the div by repeatedly firing the function manually.
Fiddle
Current js code:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
btn.onclick = function grow() {
var loop = setTimeout('grow(\'' + el + '\')', 20);
if (oswidth < target_width) {
oswidth += 5;
} else {
clearTimeout(loop);
}
el.style.width = oswidth + 'px';
}
And as always, thank you in advance!
Try this code.fiddle-https://jsfiddle.net/L8kLx7d2/
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
var loop;
function grow() {
if (oswidth < target_width) {
oswidth += 5;
} else {
clearInterval(loop);
}
el.style.width = oswidth + 'px';
}
btn.onclick=function(){
loop=setInterval(grow, 1000)};
Try this:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
btn.onclick = function grow() {
if (oswidth < target_width) {
oswidth += 5;
el.style.width = oswidth + 'px';
setTimeout(grow, 20);
}
}
I'll leave it to you to puzzle over the differences.
You can call the grow function in setInterval
JS:
var el = document.getElementById('h');
var btn = document.getElementById('button1');
var oswidth = el.offsetWidth;
var target_width = 100;
function grow() {
var loop = setTimeout('grow(\'' + el + '\')', 20);
if (oswidth < target_width) {
oswidth += 5;
} else {
clearTimeout(loop);
}
el.style.width = oswidth + 'px';
}
setInterval(grow, 1000);
Demo: http://jsfiddle.net/lotusgodkk/jeq834de/1/
There are three solutions. The first is using recursive setTimeout:
function grow(time) {
if (oswidth < target_width) {
oswidth += 5;
el.style.width = oswidth + 'px';
setTimeout(function() {grow(time);}, time);
}
}
The second is to use setInterval as described in the answer of K K.
The third is my personal favorite, using the transition css attribute.

Google maps rectangle/polygon with title

How can I add title to google.maps.Rectangle and google.maps.Polygon? The title attribute is not available within RectangleOptions. I tried it and it doesn't work
(it is possible for google.maps.Marker, so I guess it should be for rectangle and polygon too).
If there is no clean solution via google maps, woudln't it be possible to just get the DOM element of the rectangle and add title attribute with jQuery? So we might possibly reduce the question to "How to get the DOM element of google maps rectangle/polygon?"
You can mimic the "title" tooltip with InfoBox (download here). It's a bit convoluted, but by setting the right options you can make it look more like a browser tooltip than what I'm showing.
http://jsfiddle.net/vF7u2/
I found this online that helped me do tooltips on polygons,
from http://philmap.000space.com/gmap-api/poly-hov.html:
var tooltip=function(){
var id = 'tt';
var top = 3;
var left = 3;
var maxw = 200;
var speed = 10;
var timer = 20;
var endalpha = 95;
var alpha = 0;
var tt,t,c,b,h;
var ie = document.all ? true : false;
return{
show:function(v,w){
if(tt == null){
tt = document.createElement('div');
tt.setAttribute('id',id);
t = document.createElement('div');
t.setAttribute('id',id + 'top');
c = document.createElement('div');
c.setAttribute('id',id + 'cont');
b = document.createElement('div');
b.setAttribute('id',id + 'bot');
tt.appendChild(t);
tt.appendChild(c);
tt.appendChild(b);
document.body.appendChild(tt);
tt.style.opacity = 0;
tt.style.filter = 'alpha(opacity=0)';
document.onmousemove = this.pos;
}
tt.style.visibility = 'visible';
tt.style.display = 'block';
c.innerHTML = v;
tt.style.width = w ? w + 'px' : 'auto';
if(!w && ie){
t.style.display = 'none';
b.style.display = 'none';
tt.style.width = tt.offsetWidth;
t.style.display = 'block';
b.style.display = 'block';
}
if(tt.offsetWidth > maxw){tt.style.width = maxw + 'px'}
h = parseInt(tt.offsetHeight) + top;
clearInterval(tt.timer);
tt.timer = setInterval(function(){tooltip.fade(1)},timer);
},
pos:function(e){
var u = ie ? event.clientY + document.documentElement.scrollTop : e.pageY;
var l = ie ? event.clientX + document.documentElement.scrollLeft : e.pageX;
tt.style.top = (u - h) + 'px';
tt.style.left = (l + left) + 'px';
},
fade:function(d){
var a = alpha;
if((a != endalpha && d == 1) || (a != 0 && d == -1)){
var i = speed;
if(endalpha - a < speed && d == 1){
i = endalpha - a;
}else if(alpha < speed && d == -1){
i = a;
}
alpha = a + (i * d);
tt.style.opacity = alpha * .01;
tt.style.filter = 'alpha(opacity=' + alpha + ')';
}else{
clearInterval(tt.timer);
if(d == -1){tt.style.display = 'none'}
}
},
hide:function(){
clearInterval(tt.timer);
tt.timer = setInterval(function(){tooltip.fade(-1)},timer);
}
};
}();
Also, Please see this SO discussion about the same topic:
Tooltip over a Polygon in Google Maps

Categories