Right now I currently have a slider and two images on my Google ad
input class="gwd-input-13xh" type="range" min="0" max="50" value="25" id="slider" oninput="getInput(this.value, this.max)">
.img_1 {
position: absolute;
width: 180px;
height: 130px;
left: 62px;
top: 1px;
-webkit-filter: blur(5px);
opacity: .8;
}
.img_2 {
position: absolute;
width: 180px;
height: 130px;
left: 62px;
top: 1px;
-webkit-filter: blur(5px);
opacity: .8;
}
This slider, if moved right of slider value(higher 25) should remove blur and set opacity to 1. If moved left of slider value(lower 25) then vice versa occurs. Here is the current code I have to do this:
function getInput(value, max) {
var img_1 = document.getElementById("img_1");
var img_2 = document.getElementById("img_2");
var sliderPercentage = (value / max).toFixed(2);
img_1.style.opacity = 1 - sliderPercentage
setBlur(img_1, (10 * sliderPercentage).toFixed(2));
img_2.style.opacity = sliderPercentage;
setBlur(img_2, 10 - (10 * sliderPercentage).toFixed(2));
}
function setBlur(ele, value) {
if (ele.style.hasOwnProperty('filter')) {
ele.setAttribute("style", "-webkit-filter:blur(" + value + "px)")
}
}
This code works flawlessly. However, for whatever reason, the opacity will not change. IDK if it is because the opacity is set in stone when working within GWD. If you console.log(img_1.style.opacity = 1 - sliderPercentage) you will see the math on the code works.. it just isn't adjusting the opacity.
Any suggestions and ideas would greatly be appreciated. It also should be noted, when I do NOT run the setBlur function then the setOpacity function works. It just does not work when I am running setBlur.
Not familiar with GWD either, but I assume the problem is you are re-assigning the whole style attribute, so later alteration overrides the former. Replacing ele.setAttribute("style", "...") with
ele.style["-webkit-filter"] = "blur(" + value + "px)";
should fix your issue.
I'm not familiar with GWD but I tried it (with some minor changes):
$("#slider").change(function(){
var img_1 = document.getElementById("img_1");
var img_2 = document.getElementById("img_2");
var sliderPercentage = ($(this).val() / $(this).attr('max')).toFixed(2);
img_1.style.opacity = 1 - sliderPercentage
setBlur(img_1, (10 * sliderPercentage).toFixed(2));
img_2.style.opacity = sliderPercentage;
setBlur(img_2, 10 - (10 * sliderPercentage).toFixed(2));
});
function setBlur(ele, value) {
if (ele.style.hasOwnProperty('filter')) {
ele.setAttribute("style", "-webkit-filter:blur(" + value + "px)")
}
}
and I think it behaves as expected.
Please check full solution at:
https://jsfiddle.net/1eumfwoh/
Related
I have a little mouse speed detector (which is far from perfect) which gives me the current mouse speed every 100ms in the variable window.mouseSpeed.t.
I only implemented it because I want to have a funny animation on the bottom edge of the screen with a bar that grows with higher speeds and shrinks with lower speeds.
I want it to be animated with Element.animate().
The only problem is: How can I change the Animation's end keyframe (I only give an end frame so the browser assumes the current status as the first frame) while the animation is running?
I want to achieve that the bar smoothly changes its length.
// The code I want to have animated is below this function.
// Mouse speed tracker (I hope this isn't too horrible code):
document.addEventListener('DOMContentLoaded', mausgeschwindigkeitVerfolgen, {once:true});
function mausgeschwindigkeitVerfolgen() { // "Mausgeschwindigkeit verfolgen" means "track mouse speed" in German
var speedX = NaN;
var speedY = NaN;
var posX = NaN;
var posY = NaN;
var speed = NaN;
document.addEventListener("mousemove", function(ev){
speedX += Math.abs(ev.movementX);
speedY += Math.abs(ev.movementY);
speed = 10*Math.sqrt(ev.movementX**2+ev.movementY**2);
window.mousePosition = {x:posX = ev.clientX,y:posY = ev.clientY};
}, false);
setInterval(function(){
[window.mouseSpeed, window.mousePosition] = [{x:speedX,y:speedY,t:speed}, {x:posX,y:posY}]; // Werte in window.mouseSpeed und window.mouseDistance speichern
speed = totalX = totalY = 0;
}, 100);
window.mausgeschwindigkeitVerfolgen = () => {return {speed:window.mouseSpeed, pos:window.mousePosition};};
return {speed:window.mouseSpeed, pos:window.mousePosition};
}
// --- This is the code I want to have animated: ---
setInterval(() => {
document.querySelector('div#mouseSpeedIndicator').style.width = window.mouseSpeed.t+'px';
//document.querySelector('div#mouseSpeedIndicator').animate({width:'0px'}, {duration:1000,iterations:1}); // This just keeps the bar at width 0, I want it to slowly change to any newly set width
}, 100);
div#mouseSpeedIndicator {
position: fixed;
bottom: 0px;
left: 0px;
height: 33px;
background-color: green;
max-width: 100vh;
border: 0px solid green;
border-top-right-radius: 10px;
}
<!-- What I currently have -->
<div id="mouseSpeedIndicator"></div>
First, something as simple as one additional line of the transition CSS property like e.g. ...
transition: width 1s ease-out;
... already does the job; no need for more JavaScript based computation and DOM manipulation.
But of cause the OP's script could be dramatically simplified with or even without the support of an external helper method like throttle (lodash _.throttle or underscorejs _.throttle) where the latter would create a delayed executed version of the passed function which for the OP's example-script is the 'mousemove'-handler.
This handler before being throttled (or even not throttled) could be created as a bound version of the function which actually computes the speed value and updates the indicator-node's appearance.
function handleMouseSpeedIndicatorUpdateFromBoundData(evt) {
const { movementX, movementY } = evt;
const { rootNode, timeoutId } = this;
// prevent indicator nullification at time.
clearTimeout(timeoutId);
// compute `speed`.
const speed = 10 * Math.sqrt(movementX**2 + movementY**2);
// update indicator appearance.
rootNode.style.width = `${ speed }px`;
// trigger delayed indicator nullification.
this.timeoutId = setTimeout(() => rootNode.style.width = 0, 110);
}
function initialzeMouseSpeedIndicator() {
document
.addEventListener(
'mousemove',
// create throttled version of the just created bound handler.
_.throttle(
// create handler function with bound contextual data.
handleMouseSpeedIndicatorUpdateFromBoundData.bind({
rootNode: document.querySelector('#mouseSpeedIndicator'),
timeoutId: null,
}), 100
),
false
);
}
// - no need for `'DOMContentLoaded'`
// in order to initialize the indicator.
initialzeMouseSpeedIndicator();
div#mouseSpeedIndicator {
position: fixed;
top: 0px;
left: 0px;
height: 33px;
background-color: green;
max-width: 100vh;
border: 0px solid green;
border-bottom-right-radius: 10px;
/* proposed change(s) */
transition: width 1s ease-out;
/* transition: width .5s ease-in; */
/* transition: width .5s ease-in-out; */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<div id="mouseSpeedIndicator"></div>
I have this for my js and it returns a modified version of the distance between my element and my cursor... I want to use it to scale a separate element, any ideas as to how I would do that?
var elm = document.getElementById("qrcode");
elm.addEventListener("mousemove",getcordd , false)
function getcordd(ev){
var bdns = ev.target.getBoundingClientRect();
var y = ev.clientY - bdns.left;
var x = ev.clientX - bdns.top;
var d = Math.sqrt(x*x+y*y);
var s = (d*0.1)
console.log (`${s}`);
}
This is my CSS
.cursor {
position: absolute;
width: 250px;
height: 250px;
top: -50%;
left: -50%;
margin: -125px 0 0 -125px;
border-radius: 50%;
background-color: white;
transition: transform 0.8s ease-out;
mix-blend-mode: difference;
filter: grayscale(2);
pointer-events: none;
}
.cursor.is-moving {
transform: scale (var(`${s}`));
}
This is my HTML:
<div class="cursor"></div>
<main>
<h1>Find the QR code for the spotify playlist</h1>
<div id="qrcode">
<img id="QRCode" src="img/qr-code.png" alt="">
</div>
</main>
I basically made a custom curser that I would like to scale as I get closer to the element which is a QRCode
The goal would be to make it so the .cursor class scales up to 1 as it gets closer to the #qrcode. And gets smaller as it goes further away. I would like it to be relative to the window...
I am still very new to coding so I am not sure about how to do it and I have not found any information on the internet
If I correctly understand, you could do it like this
Keep in mind, that elm.addEventListener("mousemove"... would trigger function only if your cursor is already moves over elm (#qrcode), because you attach event listener to elm, not to whole window.
var elm = document.getElementById("qrcode");
var cursor = document.querySelector('.cursor');
elm.addEventListener("mousemove", function(ev) {
var distance = getcordd(ev);
cursor.style=`transform: scale(${s})`;
}, false);
function getcordd(ev) {
var bdns = ev.target.getBoundingClientRect();
var y = ev.clientY - bdns.left;
var x = ev.clientX - bdns.top;
var d = Math.sqrt(x * x - y * y);
var s = d * 0.1;
return s;
}
I want to create a loadingbar/ progressbar that loads as a value (var) increases. I cant figure out how to go around this.I have the tools. e.g. a dynamic chaning value extracted from my Firebase DB that increments on based off of a certain action. however im unsure how to go around to creating this progressbar and how to have it load based off of the dynamic incrementing value.
Any tips?
You can use something like below:
function increaseWidth(percent) {
let containerWidth = document.getElementById('progressBarContainer').clientWidth; // get the container width
let amount = Math.round(containerWidth * percent/100); // get amount of pixels the bars width needs to increase
let barWidth = document.getElementById('bar').offsetWidth; // get the current bar width
// if the bar width + amount of pixels to increase exceeds the container's width, reduce it accordingly
if(barWidth + amount > containerWidth) {
amount = containerWidth - barWidth;
clearInterval(bar); // we reached 100% so clear the interval
}
let totalPercent = Math.round((barWidth + amount) * 100/ containerWidth); // calculate the total percent finished
document.getElementById('bar').style.width = barWidth + amount + "px"; // increase bar width
document.getElementById('text').innerHTML = totalPercent + "%"; // update the percentage text
}
// this is just to mimic generating "work done" percentage
var bar = setInterval(function() {
let percentage = Math.floor(Math.random() * 10 + 1); // generate a percentage of work done
increaseWidth(percentage);
}, 1000)
#progressBarContainer {
position: relative;
float:left;
width: 200px;
height: 20px;
border: 1px solid #09f;
background-color: #000;
}
#bar {
position: relative;
float:left;
width: 0;
height: 20px;
background-color: #f00;
}
#text {
position: absolute;
height: 20px;
width: 200px;
top: 0px;
left: 0px;
color: #fff;
text-align:center;
line-height:20px;
}
<div id="progressBarContainer">
<div id="bar">
<div id="text"></div>
</div>
</div>
If you don't mind using JQuery, try using the JQuery UI Progressbar Widget. You have to first add the JQUERY UI library to your website using a <script> tag in the header:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha256-KM512VNnjElC30ehFwehXjx1YCHPiQkOPmqnrWtpccM=" crossorigin="anonymous"></script>
Then initialize the progress bar with a maximum value; if you want to use percentages, that should be 100.
$("#progressbarElementID").progressbar({
max: 100
});
Then update by writing a percent:
$("#progressbarElementID").progressbar({
value: 74 // Or whatever percent you want...
});
Repeat the update function as necessary to change the progress bar.
For a more in-depth tutorial you can refer to the API docs for this feature.
The webpage I'm trying to create has a bidirectional sliding animation on it. However the animation is only partially working. To be more precise, the animation slides up, but it only slides down partway. Here's my JavaScript:
function showLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
}
function hideLayer() {
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 315) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
}
Notice on the fourth line of the hideLayer function, I have the condition set to <= 315, this is due to the fact that setting it equal to 315 causes the element to move only a few pixels in either direction after clicking the trigger element. Here's the HTML elements I have dedicated to the animation:
<div id="mainbutton" onclick="showLayer('mainmenu'); hideLayer('mainmenu')"></div>
<div id="mainmenu" style="position: absolute; top: 690px; left: 9px;"
onclick="showLayer('mainmenu')"> </div>
And here are the styles for them:
div#mainmenu { width: 600px; height: 350px; border-style: solid; background-color:
rgb(0, 0, 0) ; border-width: 3px; border-top-right-radius: 7px; border-top-left-
radius: 7px; }
div#mainbutton { position: absolute; top: 674px; left: 12px; width: 28px; height:
28px; border-style: solid; border-color: rgb(255, 255, 255); border-width: 1px; border-
radius: 4px; }
And the fiddle : http://jsfiddle.net/JAtLA/
I had to put some of the styles inline with the HTML because the animation wouldn't work any other way. At first I thought the problem had solely lain in the if conditional of the hideLayer function. But after tweaking it I'm not so sure now.
I don't know if it's what you want but here is my answer :
There is a problem of logic in your code. You wrote
if(layerPosition<=315){
hiddenLayer.style.top = (layerPosition + 5) + "px";}
It means that if the top is 315 or less, the top will increase until it arrives to 316. But in the first function, you say it to stop at 315. So the function hideLayer will just get it moving from 1 pixel.
The solution is to tell him <400 instead of <=315 (or something higher than 400).
Here is a modified fiddle : http://jsfiddle.net/7egr7/2/
It looks like "hideLayer" will stop if (layerPosition <= 315). Is that really what you want? It happens after 1 iteration.
Note that the y axis goes down the screen (i.e. zero is at the top).
Clicking the button will call showLayer, and then hideLayer.
If the menu is open (i.e. layerPosition > 315), showLayer will not do anything (i guess that is what you intend), and hideLayer will make the menu go up by 5 (from 315 to 320).
On the next iteration of hideLayer (layerPosition <= 315) will be false, so it will not do anything.
Try this:
var open = false;
function showLayer() {
if (open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition > 315) {
hiddenLayer.style.top = (layerPosition - 5) + "px";
setTimeout("showLayer()", 20);
}
else {
open = true;
}
}
function hideLayer() {
if (!open)
return;
var hiddenLayer = document.getElementById("mainmenu");
var layerPosition = parseInt(hiddenLayer.style.top);
if (layerPosition <= 685) {
hiddenLayer.style.top = (layerPosition + 5) + "px";
setTimeout("hideLayer()", 20);
}
else {
open = false;
}
}
In the html, I would like to check if the thing is open or closed before doing anything.
<div id="mainbutton" onclick="if (!open) { showLayer('mainmenu'); } else { hideLayer('mainmenu'); }">
but layerPosition <= 685 is the only change that really matters.
I have been trying to make this work since the beginning of this week but couldn't figure it out. I have two elements in my HTML file. They are on the same vertical lane, element1 is moving 60ems to the left horizontally with each button click. I have to compare the positions of these two elements and detect whether element1 has passed the element2 with an if/else statement. When it passes I want to move the element1 to its initial position and start over. But if statement never shoots, it always jumps to else statement.
I have tried comparing following properties:
$('#elemet1').position();
$('#elemet1').position().left;
$('#elemet1').offset();
$('#elemet1').offsetLeft;
$('#elemet1').css("position");
$('#elemet1').css("left");
$('#elemet1').css("margin");
$('#elemet1').left;
I tried to compare the positions like below:
$(function () {
$("button").click(function () {
var position1 = $('#element1').css("left");
var position2 = $('#element2').css("left");
if (position1 <= position2) {
$("#element1").animate({left:'+=240em'}, 600);
}
else {
$("#element1").animate({left:'-=60em'}, 600);
}
});
});
If you can give me an answer or direct me to another post I will appreciate it. Thank you in advance.
EDIT: The style I use is below:
.element2 {
position: relative;
width: 60em;
height: 40em;
bottom: 8em;
background: rgba(242, 210, 139, 0.6);
border-radius: 1.2em;
z-index: 1;
overflow: hidden;
#element1 {
position: absolute;
margin-left: 180em;
width: 60em;
height: 40em;
z-index: 1;
}
And I should have mentioned this at the beginning: element1 is inside element2:
<div class="element2">
<img id="element1" src="image/bg1.png" />
</div>
This will give you the current position of an element:
$('#element').position().left;
If you need position relative to the document (instead of relative to a parent element) you can use:
$('#element').offset().left;
You should just be able to compare the return values of these for the different elements directly. Here's some sample code that works for me, note there is no need to parse since they always return pixel values.
var pos = Math.max($(w).scrollTop(), 38),
top = $(ballon).position().top,
dist = Math.abs(pos-top),
time = dist > 1000 ? 2000 : dist / 0.15;
if (pos + $(w).height() >= pHeight) {
pos = pHeight - bHeight - gHeight;
$(ballon).animate({'top': pos}, time, 'easeInOutSine');
}
else if (dist > 150 || pos < 100) {
$(ballon).animate({'top': pos}, time, 'easeInOutBack');
}