I have this current UI
The arrow image is just a transparent image.
I'm trying to add animation on that image.
it will just move from low to high for every page reload / after the page being loaded.
My idea to do this is using jquery
I'm playing around with this code
<img class="meter-arrow" src="{!! url('public/images/arrow.png') !!}" >
<script src="{{url('public/js/libraries/jquery_file_3_1.js')}}"></script>
<script>
$(".meter-arrow").animate({left: '250px'});
</script>
Source: https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_animation1
Is it possible to do this
It is strangely quite hard to animate a rotation using jQuery. See here about how.
I think it is easier in plain JS:
// The image element
let arrow = document.querySelector(".arrow")
// It onload --rotation value
let rotation = parseInt(getComputedStyle(arrow).getPropertyValue("--rotation"))
// Rotation on an interval
let increase = setInterval(function(){
rotation = (rotation>25) ? clearInterval(increase) : rotation+1
arrow.style.setProperty("transform", `rotate(${rotation}deg`)
},20)
.arrow{
--rotation: -90deg;
margin: 5em;
height: 160px;
width: 150px;
transform: rotate(var(--rotation));
transform-origin: 68px 118px; /* the position of the rotation point in the image */
}
<img src="https://i.imgur.com/crRJmHg.png" class="arrow">
Animations like this are also possible through CSS. See this StackBlitz example.
Reference of tranfsorm
https://www.w3schools.com/cssref/css3_pr_transform.asp
Related
I have a multilayer canvas
My html:
<div style='display:inline-block; width:100%; position:relative; top: 0px; left: 0px;'>
<div id='canvas_map_1' class='canvas canvas_map' style='overflow:scroll; background-color: #B4B4B4; z-index: 1; position:absolute; left:133px; top:0px;'></div>
<div id='canvas_map_2' class='canvas canvas_map' style='overflow:scroll; z-index: 2; position:absolute; left:133px; top:0px;'></div>
...
</div>
Given a set of coordinates I want to know if there are some images under it. I'm using Raphael and I want to try the getElementByPoint function (as alternative I could snap the coordinates to a grid and iterate all the images of the canvas to see if some have the same application point (top left corner) and it works but I thinks that will be slow, so I'm looking for faster solutions).
My javascript:
var paper_map_1 = Raphael(canvas_map_1, '100%', '100%');
var image = paper_map_1.image(image_selected, 27, 42, 33, 27);
var myimage = paper_map_1.getElementByPoint(30, 50) // or (27, 42) but shouldn't do difference
console.log(myimage) // null
myimage is null while I expected something because there is an image in that position on that canvas. I can select it, move it, etc. Off course the code is much simplified but I don't know what to add.
jsfiddle
I just started creating these Loading bar by me:
<div id="loading">
<div style="width: 650px;height: 40px;background-color: white;left:calc(50% - 325px);top: calc(50% - 20px);position: absolute;">
<div style="width:640px;height:30px;background-color:#0087cc;margin-top:5px;margin-left:5px">
<div id="myBtn" style="width:20px;height:30px;background-color:white;transition: all 2s;transition: all 0.5s ease 0s;">
</div>
</div>
</div>
</div>
The white bar is increasing from left to right , so on the end of web page i put these JS - so it makes end of loading bar and change display property o whole loading div :
$(window).load(function() {
document.getElementById("myn").style.width = "640px";
setTimeout(function(){$('#loading').fadeOut()}, 2700);
})
But I need to change the div width of that bar on the most place (for example after loading 10 picture change with to 100px and after loading another 10 pics change with to 200px ect ) on the web to create progress change of loading bar when the page will loading.
How can I change that div width on the most places of web to create continuously move of loading bar on loading web page.
And : I dont want to use Progressbar, I like to make things by myself :-)
Thanks for your help
The following code snippet wil do, as far as I understand, what you want. On a press of a button (or when some images are loaded), the width will increase by 16 pixels. This could be any variable and jQuery can be used to animate it as well. This is just an example to illustrate the principle.
$('#button').click(function() {
var width = $('.progress').width();
if (width < 256) {
width = width + 16;
$('.progress').width(width)
}
});
div.progress-bar {
width: 256px;
height: 32px;
border: 1px solid black;
}
div.progress {
width: 0px;
height: 100%;
background-color: #e0e0e0;
}
button#button {
margin-top: 32px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress-bar">
<div class="progress">
</div>
</div>
<button id="button">MORE PROGRESS!</button>
Finally i Use this code to change div width on the place of loading web :
//First is width 20 in the css
#myBtn {width:20px;height:30px;background-color:white;transition: all 0.5s ease 0s;}
**The HTML :**
// width 62.5% after load div#2013
$('#2013').load("load" , function() {
$('#myBtn').css('width', '62.5%');
});
some images
//last 100% after load div#2010 with images and with fadeout
$('#2010').load("load" , function() {
$('#myBtn').css('width', '100%');
setTimeout(function(){$('#loading').fadeOut()}, 2700);
});
I have a scrollable div container fits multiple "pages" (or div's) inside of it's container.
My goal is to, at any given moment, figure out where inside my red container does it reach the top of my scrollable container. So it can be a constant on scroll event, or a button that triggers this task.
So for example. If I have a absolute div element inside one of my red boxes at top:50px. And if I scroll to where that div element reaches the top of my scrollable container. The trigger should say that I am at 50px of my red container.
I'm having a hard time grasping how to accomplish this but I've tried things like:
$("#pageContent").scroll(function(e) {
console.log($(this).scrollTop());
});
But it doesn't take into account the separate pages and I don't believe it it completely accurate depending on the scale. Any guidance or help would be greatly appreciated.
Here is my code and a jsfiddle to better support my question.
Note: If necessary, I use scrollspy in my project so I could target which red container needs to be checked.
HTML
<div id="pageContent" class="slide" style="background-color: rgb(241, 242, 247); height: 465px;">
<div id="formBox" style="height: 9248.627450980393px;">
<div class="trimSpace" style="width: 1408px; height: 9248.627450980393px;">
<div id="formScale" style="width: 816px; -webkit-transform: scale(1.7254901960784315); display: block;">
<form action="#" id="XaoQjmc0L51z_form" autocomplete="off">
<div class="formContainer" style="width:816px;height:1056px" id="xzOwqphM4GGR_1">
<div class="formContent">
<div class="formBackground">
<div style="position:absolute;top:50px;left:100px;width:450px;height:25px;background-color:#fff;color:#000;">When this reaches the top, the "trigger" should say 50px"</div>
</div>
</div>
</div>
<div class="formContainer" style="width:816px;height:1056px" id="xzOwqphM4GGR_2">
<div class="formContent">
<div class="formBackground"><div style="position:absolute;top:50px;left:100px;width:450px;height:25px;background-color:#fff;color:#000;">This should still say 50px</div></div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
CSS
#pageContent {
position:relative;
padding-bottom:20px;
background-color:#fff;
z-index:2;
overflow:auto;
-webkit-overflow-scrolling: touch;
-webkit-transform: translate(0, 0);
-moz-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
}
#formBox {
display: block;
position: relative;
height: 100%;
padding: 15px;
}
.trimSpace {
display: block;
position: relative;
margin: 0 auto;
padding: 0;
height: 100%;
overflow: hidden;
}
#formScale::after {
display: block;
content:'';
padding-bottom:5px;
}
#formScale {
position:relative;
width:816px;
margin:0;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform-origin: 0 0;
-ms-transform-origin: 0 0;
}
.formContainer {
position:relative;
margin : 0 auto 15px auto;
padding:0;
}
.formContent {
position:absolute;
width:100%;
height:100%;
}
.formBackground {
width:100%;
height:100%;
background-color:red;
}
JS
var PAGEWIDTH = 816;
$(window).resize(function (e) {
zoomProject();
resize();
});
function resize() {
$("#pageContent").css('height', window.innerHeight - 45 + 'px');
}
function zoomProject() {
var maxWidth = $("#formBox").width(),
percent = maxWidth / PAGEWIDTH;
$("#formScale").css({
'transform': 'scale(' + percent + ')',
'-moz-transform': 'scale(' + percent + ')',
'-webkit-transform': 'scale(' + percent + ')',
'-ms-transform': 'scale(' + percent + ')'
});
$(".trimSpace").css('width', (PAGEWIDTH * percent) + 'px');
$("#formBox, .trimSpace").css('height', ($("#formScale").height() * percent) + 'px');
}
zoomProject();
resize();
EDIT:
I don't think I am conveying a good job at relaying what I want to accomplish.
At the moment there are two .formContainer's. When I scroll #pageContainer, the .formContainer divs move up through #pageContainer.
So what I want to accomplish is, when a user clicks the "ME" button or #click (as shown in the fiddle below), I'd like to know where in that particular .formContainer, is it touching the top of #pageContainer.
I do use scroll spy in my real world application so I know which .formContainer is closest to the top. So if you just want to target one .formContainer, that is fine.
I used these white div elements as an example. If I am scrolling #pageContainer, and that white div element is at the top of screen as I am scrolling and I click on "ME", the on click trigger should alert to me that .formContainer is touching the top of #pageContainer at 50px from the top. If, the the red container is just touching the top of #pageContainer, it should say it is 0px from the top.
I hope that helps clear up some misconception.
Here is an updated jsfiddle that shows the kind of action that I want to happen.
I am giving this a stab because I find these things interesting. It might just be a starting point since I have a headache today and am not thinking straight. I'd be willing to bet it can be cleaned up and simplified some.
I also might be over-complicating the approach I took, getting the first visible form, and the positioning. I didn't use the getBoundingClientRect function either.
Instead, I approached it trying to account for padding and margin, using a loop through parent objects up to the pageContent to get the offset relative to that element. Because the form is nested a couple levels deep inside the pageContent element you can't use position(). You also can't use offset() since that changes with scroll. The loop approach allowed me to factor the top margin/padding in. I haven't looked at the other solutions proposed fully so there might be a shorter way to accomplish this.
Keeping in mind that the scale will affect the ACTUAL location of the child elements, you have to divide by your scale percentage when getting the actual location. To do that I moved the scalePercentage to a global var so it was usable by the zoom function and the click.
Here's the core of what I did. The actual fiddle has more logging and junk:
var visForm = getVisibleForm();
var formTop = visForm.position().top;
var parents = visForm.parentsUntil('#pageContent');
var truOffset = 0;
parents.each(function() {
truOffset -= $(this).position().top;
});
// actual location of form relative to pageContent visible pane
var formLoc = truOffset - formTop;
var scaledLoc = formLoc / scalePercent;
Updated Fiddle (forgot to account for scale in get func): http://jsfiddle.net/e6vpq9c8/5/
If I understand your question correctly, what you want is to catch when certain descendant elements reach the top of the outer container, and then determine the position of the visible "page" (div with class formContainer) relative to the top.
If so, the first task is to mark the specific elements that could trigger this:
<div class='triggerElement' style="position:absolute;top:50px;left:100px;width:450px;height:25px;background-color:#fff;color:#000;">When this reaches the top, the "trigger" should say 50px"</div>
Then the code:
// arbitrary horizontal offset - customize for where your trigger elements are placed horizontally
var X_OFFSET = 100;
// determine once, at page load, where outer container is on the page
var outerContainerRect;
$(document).ready(function() {
outerContainerRect = $("#pageContent").get(0).getBoundingClientRect();
});
// when outer container is scrolled
$("#pageContent").scroll(function(e) {
// determine which element is at the top
var topElement = $(document.elementFromPoint(outerContainerRect.left+X_OFFSET, outerContainerRect.top));
/*
// if a trigger element
if (topElement.hasClass("triggerElement")) {
// get trigger element's position relative to page
console.log(topElement.position().top);
}
*/
var page = topElement.closest(".formContainer");
if (page.length > 0) {
console.log(-page.get(0).getBoundingClientRect().top);
}
});
EDIT: Changed code to check formContainer elements rather than descendant elements, as per your comment.
http://jsfiddle.net/j6ybgf58/23/
EDIT #2: A simpler approach, given that you know which formContainer to target:
$("#pageContent").scroll(function(e) {
console.log($(this).scrollTop() - $("#xzOwqphM4GGR_1").position().top);
});
http://jsfiddle.net/rL4Ly3yy/5/
However, it still gives different results based on the size of the window. This seems unavoidable - the zoomProject and resize functions are explicitly resizing the content, so you would have to apply the inverse transforms to the number you get from this code if you want it in the original coordinate system.
I do not fully understand what it is that you are needing, but if i am correct this should do the trick
$("#pageContent").scroll(function(e) {
// If more then 50 pixels from the top has been scrolled
// * if you want it to only happen at 50px, just execute this once by removing the scroll listener on pageContent
if((this.scrollHeight - this.scrollTop) < (this.scrollHeight - 50)) {
alert('it is');
}
});
ScrollHeight is the full height of the object including scrollable pixels.
ScrollTop is the amount of pixels scrolled from the top.
You can use waypoints to detect the position of divs based on where you're scrolling.
Here is a link to their official website's example: http://imakewebthings.com/waypoints/shortcuts/inview/
So I almost have my code working how I want, but can't get my animation synched together just right. I am trying to animate a cursor highlighting text, and then clicking on a button. The problem is that the cursor is either too slow or too fast. I am trying to make this dynamic so that no matter how long the text is I can still have the animation synch. I know that it is probably just a math issue, but can't quite get my head around it. Something about trying to match pixels with milliseconds is making my head spin. Please help before I pull out all my hair. Thanks.
Here is the html
<p><span id="container">I need to be highlighted one character at a time</span>
<input id="click" type="button" value="click me"/></p>
<img src="http://dl.dropbox.com/u/59918876/cursor.png" width="16"/>
Here is the CSS
#container{
font-size: 16px;
margin-right: 10px;
}
.highlight{
background: yellow;
}
img{
position: relative;
top: -10px;
}
And the javascript
function highlight(){
var text = $('#container').text(); //get text of container
$('#click').css('border','none'); //remove the border
$('img').css('left', '0px'); //reset the cursor left
$('img').animate({left: $('#container').width() + 40}, text.length*70); //animation of cursor
$('#container').html('<span class="highlight">'+text.substring(0,1)+'</span><span>'+text.substring(1)+'</span>'); //set the first html
(function myLoop (i) {//animation loop
setTimeout(function () {
var highlight = $('.highlight').text();
var highlightAdd = $('.highlight').next().text().substring(0,1);;
var plain = $('.highlight').next().text().substring(1);
$('#container').html('<span class="highlight">'+highlight+highlightAdd+'</span><span>'+plain+'</span>');
if (--i) myLoop(i);// decrement i and call myLoop again if i > 0
}, 70)
})(text.length);
setTimeout(function () {
$('#click').css('border','1px solid black');
}, text.length*85);
}
highlight();
var intervalID = setInterval(highlight, $('#container').text().length*110);
//clearInterval(intervalID);
Here is a link to the fiddle I have been playing around in.
This will probably get me down voted but maybe you will get some better idea...
Fiddle Here
$(document).ready(function() {
$('p').click(function(){
$('span').animate({'width':'100'},1000);
$('.cursor').animate({marginLeft: 100},1000);
});
});
Thanks to Dejo, I was able to modify my code to make this work exactly as I wanted. It was much easier to increase the width of one span rather than trying to expand one span while shrinking another. This also allowed me to have both the cursor moving and the span width increasing animations run in sync.
The HTML
<p><span id="highlight"></span><span id="container">I need to be highlighted one character at a time</span><input id="click" type="button" value="click me"/></p>
<img id="cursor" src="http://dl.dropbox.com/u/59918876/cursor.png" width="16"/>
The CSS
p{
position: relative;
font-size: 16px;
}
#highlight{
position: absolute;
background-color:yellow;
height:20px;
z-index:-50;
}
#cursor{
position: relative;
top: -10px;
}
#click{
margin-left; 10px;
}
And the javascript
function highlight(){
var textLength = $('#container').text().length;
$('#click').css('border','none'); //remove the border
$('#cursor').css('left', '0px'); //reset the cursor left
$('#highlight').width(0);
$('#highlight').animate({width: $('#container').width()}, textLength * 70);
$('#cursor').animate({left: '+='+$('#container').width()} , textLength * 70, function(){
$('#cursor').animate({left: '+=30'} , textLength * 20);
});
setTimeout(function () {
$('#click').css('border','1px solid black');
}, textLength*100);
}
highlight();
var intervalID = setInterval(highlight, $('#container').text().length*120);
//clearInterval(intervalID);
I realize it's quite a bit late, but here's a bit of help (for future reference).
The JQuery animate function is, by default, set an easing of swing, which means that the speed of the animation will vary throughout (see here).
To (kind of) fix the problem, I added the linear option to the animate method for the cursor, and increased its speed slightly.
You can see this new version at JSFiddle.
However, since the setTimeout loop can be slowed for some reasons, the animation may not be in sync.
How can I fade one image into another with jquery? As far as I can tell you would use fadeOut, change the source with attr() and then fadeIn again. But this doesn't seem to work in order. I don't want to use a plugin because I expect to add quite a few alterations.
Thanks.
In the simplest case, you'll need to use a callback on the call to fadeOut().
Assuming an image tag already on the page:
<img id="image" src="http://sstatic.net/so/img/logo.png" />
You pass a function as the callback argument to fadeOut() that resets the src attribute and then fades back using fadeIn():
$("#image").fadeOut(function() {
$(this).load(function() { $(this).fadeIn(); });
$(this).attr("src", "http://sstatic.net/su/img/logo.png");
});
For animations in jQuery, callbacks are executed after the animation completes. This gives you the ability to chain animations sequentially. Note the call to load(). This makes sure the image is loaded before fading back in (Thanks to Y. Shoham).
Here's a working example
$("#main_image").fadeOut("slow",function(){
$("#main_image").load(function () { //avoiding blinking, wait until loaded
$("#main_image").fadeIn();
});
$("#main_image").attr("src","...");
});
Well, you can place the next image behind the current one, and fadeOut the current one so that it looks like as though it is fading into the next image.
When fading is done, you swap back the images. So roughly:
<style type="text/css">
.swappers{
position:absolute;
width:500px;
height:500px;
}
#currentimg{
z-index:999;
}
</style>
<div>
<img src="" alt="" id="currentimg" class="swappers">
<img src="" alt="" id="nextimg" class="swappers">
</div>
<script type="text/javascript">
function swap(newimg){
$('#nextimg').attr('src',newimg);
$('#currentimg').fadeOut(
'normal',
function(){
$(this).attr('src', $('#nextimg').attr('src')).fadeIn();
}
);
}
</script>
Are you sure you're using the callback you pass into fadeOut to change the source attr and then calling fadeIn? You can't call fadeOut, attr() and fadeIn sequentially. You must wait for fadeOut to complete...
Old question but I thought I'd throw in an answer. I use this for the large header image on a homepage. Works well by manipulating the z-index for the current and next images, shows the next image right under the current one, then fades the current one out.
CSS:
#jumbo-image-wrapper
{
width: 100%;
height: 650px;
position: relative;
}
.jumbo-image
{
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
HTML:
<div id="jumbo-image-wrapper">
<div class="jumbo-image" style="background-image: url('img/your-image.jpg');">
</div>
<div class="jumbo-image" style="background-image: url('img/your-image-2'); display: none;">
</div>
</div>
Javascript (jQuery):
function jumboScroll()
{
var num_images = $("#jumbo-image-wrapper").children(".jumbo-image").length;
var next_index = jumbo_index+1;
if (next_index == num_images)
{
next_index = 0;
}
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).css("z-index", "10");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).css("z-index", "9");
$("#jumbo-image-wrapper").children(".jumbo-image").eq(next_index).show();
$("#jumbo-image-wrapper").children(".jumbo-image").eq(jumbo_index).fadeOut("slow");
jumbo_index = next_index;
setTimeout(function(){
jumboScroll();
}, 7000);
}
It will work no matter how many "slides" with class .jumbo-image are in the #jumbo-image-wrapper div.
For those who want the image to scale according to width percentage (which scale according to your browser width), obviously you don't want to set height and width in PIXEL in CSS.
This is not the best way, but I don't want to use any of the JS plugin.
So what can you do is:
Create one same size transparent PNG and put an ID to it as
second-banner
Name your original image as first-banner
Put both of them under a DIV
Here is the CSS structure for your reference:
.design-banner {
position: relative;
width: 100%;
#first-banner {
position: absolute;
width: 100%;
}
#second-banner {
position: relative;
width: 100%;
}
}
Then, you can safely fade out your original banner without the content which placed after your image moving and blinking up and down