I have a web page that is loading images and scans across about 600+ images as the user presses next or previous. This is working fine. However, the image load time is slow so the idea is to put a processing while in place of the images until they are fully loaded. I can get the processing wheel to load perfectly fine but I cannot get it to hide once the image or document is loaded. I have tried doing this two different ways:
Attempt 1:
$('#centerImage').ready(function () {
$('.spinner').css('display', 'none');
});
Attempt 2:
$('#centerImage').ready(function () {
$('.spinner').hide();
});
I have also tried replacing the selector #centerImage on the .ready() function with document but still don't see the Processing Wheel get hidden.
What I find strange is that when I try and hide an ID instead of a Class, it works perfectly fine. I tried a 'Try Me' on W3 Schools with a simple example and hiding a class with the .hide() doesn't work there either.
Google isn't returning anything specific to any limitations with jQuery hiding classes. Is this possible or am I approaching this the wrong way?
NOTE: I'm using spin.js for the processing wheel.
All Code:
JavaScript:
EDIT: Added .load instead of .ready
var previousImage = document.getElementById("previousImage");
var centerImage = document.getElementById("centerImage");
var nextImage = document.getElementById("nextImage");
previousImage.setAttribute("src", "../.." + document.getElementById("MainContent_lblPreviousImage").innerHTML);
centerImage.setAttribute("src", "../.." + document.getElementById("MainContent_lblCenterImage").innerHTML);
nextImage.setAttribute("src", "../.." + document.getElementById("MainContent_lblNextImage").innerHTML);
$('#centerImage').load(function () {
$('.spinner').hide();
});
HTML/ASP.NET:
<div id="images">
<img id="previousImage" onload="showProgress()" alt="" src=""/>
<img id="centerImage" onload="showProgress()" alt="" src=""/>
<img id="nextImage" onload="showProgress()" alt="" src=""/>
</div>
Show Progress JavaScript File:
function showProgress () {
var opts = {
lines: 13, // The number of lines to draw
length: 20, // The length of each line
width: 10, // The line thickness
radius: 30, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 0, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#000', // #rgb or #rrggbb or array of colors
speed: 1, // Rounds per second
trail: 60, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: '50%', // Top position relative to parent
left: '50%' // Left position relative to parent
};
var target = document.getElementById('images');
var spinner = new Spinner(opts).spin(target);
}
Thanks in advance for any helpful input.
As #Barmar $("#centerimage").ready() is the same as $(document).ready(). There's no separate ready event for each element, it just applies to the whole DOM.
Ready is used to check if the DOM is ready and the load is used to check if the Content is loaded.
Use load instead of ready:
$('#centerImage').load(function () {
Related
I have two small green divs within my canvas. It can be drag within the canvas with an id myid_templates_editor_canvas, with the use of the code below:
myid_templates_editor_make_draggable('div1');
myid_templates_editor_make_draggable('div2');
// Make an element draggable within the canvas
function myid_templates_editor_make_draggable(id){
jQuery('#' + id).draggable({
cursor: 'move',
cursorAt: { top: 56, left: 56 },
containment: '#myid_templates_editor_canvas',
});
}
See images below:
I have made a line between 2 draggable divs using jsPlumb.
var jsPlumb_instance = jsPlumb.getInstance();
var endpointOptions = {
anchor:'BottomCenter',
maxConnections:1,
endpoint:['Rectangle',{width:'0px', height:'0px' }],
paintStyle:{fillStyle:'black'},
connectorStyle : { lineWidth: '1px' , strokeStyle: 'black' },
connector : ['Straight'],
setDragAllowedWhenFull:true,
};
div1Endpoint = jsPlumb_instance.addEndpoint('div1', endpointOptions);
div2Endpoint = jsPlumb_instance.addEndpoint('div2', endpointOptions);
jsPlumb_instance.connect({
source:div1Endpoint,
target:div2Endpoint,
});
jsPlumb_instance.draggable('div1');
jsPlumb_instance.draggable('div2');
I dont want the line outside the canvas border. See 3rd picture.
I want the line to be contained within the canvas with an id myid_templates_editor_canvas.See the image below:
I tried changing part of the code above with the the code below, with no luck.
jsPlumb_instance[id].draggable(id1, {containment:'#myid_templates_editor_canvas'});
jsPlumb_instance[id].draggable(id2 , {containment:'#myid_templates_editor_canvas'});
Yes, the two points was somehow constrained because the length of the maximum line was limited but still goes out of the border of the canvas.Below is the html set-up of the canvas and two points.
<table>
<tr>
<td>
<canvas id="myid_templates_editor_canvas"></canvas>
<div id="div1"></div>
<div id="div2"></div>
</td>
</tr>
</table>
I worked with jsPlumb for quite long already and I remembered it need to refer to a lot of library.
Because jsPlumb using draggable feature from jQuery UI, you can read this article for understanding how it is being worked.
https://jqueryui.com/draggable/#constrain-movement
In your case, myid_templates_editor_canvas will not be consider as the containment, it is for drawing only. So I suggest you to modify your html as below try, let me know your result as well.
I put an ID for table element and it will be the containment for 2 end points. The containment must be an element that contains child element - in the other words - parent element.
myid_templates_editor_make_draggable('div1');
myid_templates_editor_make_draggable('div2');
// Make an element draggable within the canvas
function myid_templates_editor_make_draggable(id){
jQuery('#' + id).draggable({
cursor: 'move',
cursorAt: { top: 56, left: 56 },
containment: '#main-container',
});
}
<table id="main-container">
<tr>
<td>
<canvas id="myid_templates_editor_canvas"></canvas>
<div id="div1"></div>
<div id="div2"></div>
</td>
</tr>
</table>
Actually you can set containment via jsPlumb. See my jsFiddle. The reason why your solution did not work is that you have set draggable via jsPlumb, not jQuery. They do not know about it other, so can not work together. You need to provide options to draggable function:
jsPlumb_instance.draggable(element, { containment:true });
To know more about draggable in jsPlumb see help. You can set containment container explicitly when you get instance of jsPlumb:
var jsPlumb_instance = jsPlumb.getInstance({ Container:"inner" });
You can also specify DragOptions and DropOptions if you need (more info).
It is better to set draggable via jsPlumb, as a plus, then no need to call repaint after dragging is finished. A huge performance benefit with a lot of elements.
A common feature of interfaces using jsPlumb is that the elements are
draggable. You should use the draggable method on a jsPlumbInstance to
configure this:
myInstanceOfJsPlumb.draggable("elementId");
...because if you don't, jsPlumb won't know that an element has been
dragged, and it won't repaint the element.
I had made a solution to my problem. I changed my code above to to code below:
myid_templates_editor_make_draggable('div1');
myid_templates_editor_make_draggable('div2');
//Make an element draggable within the canvas
function myid_templates_editor_make_draggable(id){
jQuery('#' + id).draggable({
cursor: 'move',
cursorAt: { top: 56, left: 56 },
containment: '#myid_templates_editor_canvas',
drag: function(e, ui){
jsPlumb_instance.repaintEverything();
},
});
}
I had also omit the line of code that make JsPlumb two endpoints draggable.
var jsPlumb_instance = jsPlumb.getInstance();
var endpointOptions = {
anchor:'BottomCenter',
maxConnections:1,
endpoint:['Rectangle',{width:'0px', height:'0px' }],
paintStyle:{fillStyle:'black'},
connectorStyle : { lineWidth: '1px' , strokeStyle: 'black' },
connector : ['Straight'],
setDragAllowedWhenFull:true,
};
div1Endpoint = jsPlumb_instance.addEndpoint('div1', endpointOptions);
div2Endpoint = jsPlumb_instance.addEndpoint('div2', endpointOptions);
jsPlumb_instance.connect({
source:div1Endpoint,
target:div2Endpoint,
});
Hope it helps everyone that is going through the same problem with me.
I've created a line animation with RaphaelJS (see jsfiddle here - http://jsfiddle.net/7n040zdu/). I'm attempting to create a animation that occurs after this one takes place that is basically an erasing of the initial animation. That is, the line animated out the same way that it is animated in - along the same path, the same duration, the same direction.
I have tried just animating another path on top, but that solution is not preferable. If the initial path overlaps itself, then erasing with another path would reveal that the animation is not 'erasing' but rather being overlapped.
I am having trouble finding something in the Raphael documentation that would achieve anything similar to this.
Relevant code below:
HTML
<body>
<div class='drawings' id="draw0"></div>
</body>
CSS
body {
background-color: black;
}
JS
var animateLine = function(canvas, colorNumber, strokeWidth, pathString) {
var line = canvas.path(pathString).attr({
stroke: colorNumber
});
var length = line.getTotalLength();
$('path[fill*="none"]').animate({
'to' : 1
}, {
duration: 1000,
step: function (pos, fx) {
var offset = length * fx.pos;
var subpath = line.getSubpath(0, offset);
canvas.clear();
canvas.path(subpath).attr({
stroke: colorNumber,
"stroke-dasharray" : "",
"stroke-width" : strokeWidth
});
}
});
}
var canvas = new Raphael('draw0', 50,50);
var drawPath1 = 'M0.767,0.915 M48.538,20.228L0.767,0.915l3.896,39.312L48.538,20.228L37.663';
animateLine(canvas, '#FFF', '1.5', drawPath1);
Based on #Ian's comment on the original question, I was able to use a single path and then animate the dashoffset of the svg, but it took some further changing in order to get that actually working correctly.
Initially, the SVG path's css is set with the following parameters: 'stroke-dasharray': '9999px' and 'stroke-dashoffset': '9999px'. The stroke-dashoffset is then animated from 9999px to 9999px minus the length of the path. At the end of the initial animation, the css has to be set once again, this time: 'stroke-dasharray': '999 999' and 'stroke-dashoffset': '9999px'. At this point, the stroke-dashoffset is animated once again, this time 'stroke-dashoffset': (9999-(length of path)-100)+'px'.
A jsfiddle showing this is present here: http://jsfiddle.net/tim_m/94ze4ajj/
*Note that in the jsfiddle, I've added more paths with varying opacity and time offsets to give the illusion of a fade at the tips of the line animation.
An issue thats been plaguing me for some time now. I cant get spin.js to work on submit buttons.
Heres a fiddle:
http://jsfiddle.net/xSDGx/24/
If you comment out the submit button and instead allow the div then it works fine.
Thanks.
For reference:
<input type="submit" id="spin">
var spinner;
var opts = {
lines: 13, // The number of lines to draw
length: 5, // The length of each line
width: 2, // The line thickness
radius:5, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 58, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#fff', // #rgb or #rrggbb or array of colors
speed: 0.9, // Rounds per second
trail: 100, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: '57%', // Top position relative to parent
left: '50%' // Left position relative to parent
};
var target = document.getElementById('spin');
var spinner = new Spinner(opts).spin(target);
$(target).data('spinner', spinner);
As explained in a comment, submit buttons aren't meant to contain other elements.
This poses the issue with the question.
To get around this I have wrapped the submit button in a div with the same width and height.
<div id="wrap">
<input type="submit">
</div>
You can use a <button> element instead, which by default acts as submit button:
http://jsfiddle.net/fgnass/q6ou3dt7/
I can't seem to stop this spinner no matter what I try.
I have searched around for the way to do it but nothing I have tried works.
Fiddle:
http://jsfiddle.net/gmvT4/5/
Backup code:
var opts = {
lines: 13, // The number of lines to draw
length: 5, // The length of each line
width: 2, // The line thickness
radius: 5, // The radius of the inner circle
corners: 1, // Corner roundness (0..1)
rotate: 58, // The rotation offset
direction: 1, // 1: clockwise, -1: counterclockwise
color: '#fff', // #rgb or #rrggbb or array of colors
speed: 0.9, // Rounds per second
trail: 100, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: '50%', // Top position relative to parent
left: '50%' // Left position relative to parent
};
var target = document.getElementById('foo');
$(document).on('click', '#spin', function () {
var spinner = new Spinner(opts).spin(target);
});
$(document).on('click', '#stop', function () {
$("#foo").data('spinner').stop();
});
<div id="foo"></div>
<button id="spin">Spin!</button>
<button id="stop">Stop!</button>
Thanks for any help! Craig.
Uncaught TypeError: Cannot read property 'stop' of undefined
This error tells you something. You're trying to run .stop() on $("#foo").data('spinner'). Instead, use the instance created by spinner, which you'll need to first declare outside of the scope of that click event.
var spinner;
$(document).on('click','#spin',function(){
spinner = new Spinner(opts).spin(target);
});
$(document).on('click','#stop',function(){
spinner.stop();
});
Updated fiddle c/o René Roth
I'm using spin.js ( http://fgnass.github.com/spin.js/) while a large full width/height image loads. The problem is I'm having trouble stopping the spinner. The stop() method doesn't seem to work. There's what I've got:
$(document).ready(function($) {
var img = new Image();
img.src = $('#top-bg').css('background-image').replace(/url\(|\)/g, '');
img.onload = function(){
$("#top-bg").spinner.stop();
$(".top-bar").delay(1500).fadeIn(5000);
$("#arrow, #arrowrt, #top-icons").delay(5000).fadeIn(5000);
};
});
I also tried
.spin(false)
and
.data('spinner').stop()
This is the spinner settings:
$(document).ready(function($) {
var opts = {
lines: 9, // The number of lines to draw
length: 11, // The length of each line
width: 4, // The line thickness
radius: 10, // The radius of the inner circle
rotate: 0, // The rotation offset
color: '#fff', // #rgb or #rrggbb
speed: 0.9, // Rounds per second
trail: 54, // Afterglow percentage
shadow: false, // Whether to render a shadow
hwaccel: false, // Whether to use hardware acceleration
className: 'spinner', // The CSS class to assign to the spinner
zIndex: 2e9, // The z-index (defaults to 2000000000)
top: 'auto', // Top position relative to parent in px
left: 'auto' // Left position relative to parent in px
};
var target = document.getElementById('top-bg');
var spinner = new Spinner(opts).spin(target);
});
You need to store the spinner instance somewhere - in a way that you can access it when you need it to stop the spinning:
var spinner = new Spinner(opts).spin(target);
$(target).data('spinner', spinner);
And now you're able to stop it like this:
$('#top-bg').data('spinner').stop();
You can stop spinner without instance:
$(target).spin(false);
This seems to work across browsers and uses less code:
$(".spinner").remove();
Remove all DOM of containter, example:
<style type="text/css">.loader{ display: none; }</style>
<div>
<span class="loader"></span>
<span>Foo</span>
</div>
If need apply sping append it in
$('.loader').show().spin();
And destroy:
$('.loader').hide().empty();
Remember, jQuery.empty() automaticaly remove all DOM of object before destroy.