I would like to implement a swipe gesture to replace the current Next/Prev-buttons in my web app. I figure I'll use either jQuery Mobile, QuoJS or Hammer.js to recognize the swipe gestures.
But how can I go about implementing the swipe animation (similar to this) to go with the gestures?
I'm not flipping between images as in the example, but html sections mapping onto Backbone Model Views.
This finally "solved" it. I'm using jQuery-UI with a slide effect, but it's not looking as good as I had hoped, I want it to look more like on iOS using Obj-C. But it will have to do.
var handleSwipeEvents = function() {
$(function() {
$('#myId').on('swipeleft', swipeHandler);
$('#myId').on('swiperight', swipeHandler);
function swipeHandler(event) {
function slideEffect(swipeLeft, duration) {
var slideOutOptions = {"direction" : swipeLeft ? "left": "right", "mode" : "hide"};
$('#myId').effect("slide", slideOutOptions, duration, function() { // slide out old data
var slideInOptions = {"direction" : swipeLeft ? "right" : "left", "mode" : "show"};
$('#myId').effect("slide", slideInOptions, duration); // slide in new data
// Alter contents of element
});
}
var swipeLeft = (event.type === "swipeleft");
slideEffect(swipeLeft, 300);
}
});
};
I have a feeling one can achieve better results using CSS3 and transition, but I haven't succeeded with that.
Related
I use vivus.js to animate SVGs. I wonder what is the best way to use it in combination with intersection observer, concerning performance.
On my page are several sections, including inline svgs. These svgs should be animated when scrolling down the page, stop when leaving the viewport und start again when the container is observed again.
It works but i am not sure if this is the best way to build vivus objects und play them again and again in this way.
These solution seems to crash firefox performance..
I welcome all comments, suggestions and proposed improvements.
$( document ).ready(function() {
//Define observed Items
var myItems = document.querySelectorAll(".observed-item");
//Define observer Options
var observeroptions = {
root: null,
rootMargin: "-35% 0% -35% 0%",
threshold: 0,
};
//Create new Observer Object
var observer = new IntersectionObserver(function(entries, observer){
entries.forEach(function(entry){
//Define Index Variable
var myIndex = $(entry.target).index();
var myvivus = new Vivus("item-svg" + myIndex, {
duration: 150,
start: 'manual'
},
function () {
$(entry.target).addClass('callback-item-animation');
}
)
if (entry.intersectionRatio > 0) {
//Add class to Entry Target
$(entry.target).addClass("item-animate");
myvivus.reset().play();
} else {
//Remove animated Class from observed Item
$(entry.target).removeClass("item-animate");
myvivus.stop().reset();
}
});
},observeroptions);
myItems.forEach(function(myItem) {
observer.observe(myItem);
});
});
I created a pen:
https://codepen.io/Milenoi/pen/JBxgOG
Please Note: without Polyfill works in Chrome + Firefox
As you can see, the animation doesn't work as expected, the svg animation should stop when leaving observer and start again wenn element is intersected again..
Your hoisting observer and clashing it in the function. Add var or let before observer =, then change the name of observer in that function to something unique. Also qualify everything with window. Or context. That should improve the performance marginally
how can I display data point on bar in barchart?
I don't want to use datatip or tooltip which will highlight data points only when they are moused over.
I want to display the data point always on the bar.
is there any right way to get it?
thanks.
I want exactly like this
following is my code
<p:barChart id="barChartId" value="#{myBean.myModel}"
orientation="horizontal"
stacked="true" extender="ext" animate="true" shadow="false" />
<h:outputScript>
function ext() {
this.cfg.highlighter = {
useAxesFormatters: false,
tooltipAxes: 'x'
};
this.cfg.legend = {
show: true,
location: 'ne',
placement: 'outside'
};
this.cfg.seriesDefaults = {
pointLabels : { show: true },
};
}
</h:outputScript>
here, highlighter and legend are working fine but point labels are not displaying on bar
Not sure if it will work...
Use the extender of the <p:barChart , like this:
<p:barChart value="#{myBean.myModel}" widgetVar="myBarChart" extender="my_ext"/>
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
renderer:$.jqplot.BarRenderer,
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
or this
<script type="text/javascript">
function my_ext() {
this.cfg.seriesDefaults = {
pointLabels: {show: true}
};
this.cfg.stackSeries: true;
}
</script>
Also take a look at the jqplot examples : Bar charts
Just in case someone doesn't crawl through the comments of the marked answer, as I didn't do in the first place.
The problem basically is not the configuration of the pointLabelselement, but rather that primefaces (as of 4.0) in its original state does not ship with the needed plugin of jqPlot included.
Therefore actually the solution is to make the needed plugin jqplot.pointLabels.min.js available. From a ticket in the bug tracker (http://code.google.com/p/primefaces/issues/detail?id=5378) I extracted, that primefaces uses jqPlot version 1.0.8.
download jqplot 1.0.8 from https://bitbucket.org/cleonello/jqplot/downloads/
add the plugin to your project (e.g. src/main/webapp/resources/jqplot-plugins)
add the plugin as script to your page (<h:outputScript library="jqplot-plugins" name="jqplot.pointLabels.min.js" />)
I'm trying to implement dragging an item onto a jquery slider. For example, if the item is dropped onto 86% of the slider I would like to POST this position to the server so the item can be place 86% along the result set on the server.
How do you detect dropping onto a jQuery slider and the percentage POSTed to the server?
Since I'm not so good at explaining things, I made a jsFiddle for you. Although this might not be exactly what your looking for, it should be a good starting point!
Here's the code :
$(function () {
//the draggable object
$("#dragobject").draggable();
//Prepare the slider
var range = 100,
sliderDiv = $("#slider");
// Activate the UI slider
sliderDiv.slider({
min: 0,
max: range,
create : function(){
$(this).find(".ui-slider-handle").hide();
}
});
// Number of tick marks on slider
var position = sliderDiv.position(),
sliderWidth = sliderDiv.width(),
minX = position.left,
maxX = minX + sliderWidth,
tickSize = sliderWidth / range;
//Set slider as droppable
sliderDiv.droppable({
//on drop
drop: function (e, ui) {
var finalMidPosition = $(ui.draggable).position().left + Math.round($("#dragobject").width() / 2);
//If within the slider's width, follow it along
if (finalMidPosition >= minX && finalMidPosition <= maxX) {
var val = Math.round((finalMidPosition - minX) / tickSize);
sliderDiv.slider("value", val);
alert(val + "%");
//do ajax update here to set the position
/*$.ajax({
type: "POST",
url: url,
data: val,
success: function () {
//congrats
},
dataType: dataType
});*/
}
}
});
});
And here's the jsFiddle link : jsFiddle example
Hope it helps,
Marc.
SOURCES :
Jquery slider that slides while mouse move,
jQuery UI slider
Since you are using jQuery, lets assume you are using jQuery UI for your drag and drop. First read this: http://api.jqueryui.com/droppable/#event-drop
Then realize that you get the offset position of the dropped element relative to the droppable container as part of the event. This would be where you could compute that into percentage if you needed.
For example, dropped at position left -> 90px of a container that you know to be 100px wide means 90% is your magic number.
Or if you are using native drag and drop, check out this simple edit: http://jsbin.com/ezuke/3283/edit . If you pop a console log on the event in the drop event, you will see that it also exposes the offset of where you dropped it and you could again consume that in your calculation of %.
Is there a way of preventing a Google Maps (JS, v3) map being displayed from the get-go? I'm doing some pre-processing and would like to show my 'Loading' spinner until everything is good to go (more eloquently put, hide the map -- e.g. the container div – until all pre-processing is complete – at which point, show the map).
Hooking up the map's idle event doesn't help that much, since the map is already displayed when this event hits.
I know that the container div gets inline-styled by GMaps after loading, my first idea was to clear out the style attribute (whilst listening to the idle event), but it would be interesting to see if there is a way of creating the map and not displaying it until all pre-processing is done.
Maybe by using an argument to the new google.maps.Map constructor, or a MapOption ?
Any thoughts on this?
Thank you in advance!
Also remember to call:
google.maps.event.trigger(map, 'resize');
if you have changed the size of the <div>. A display:none <div> has no size.
Or you could just hide it like with css visablility or css opacity.
$("#GoogleMap").css({ opacity: 0, zoom: 0 });
initialize();
google.maps.event.addListener(map,"idle", function(){
$('#Loader').hide();
$("#GoogleMap").css({ opacity: 1, zoom: 1 });
});
This works for me. I'm using the JQuery library.
$(document).ready(function(){
$('#Checkbox').click(function(){
$('#googleMapDiv').toggle();
initialize(); // initialize the map
});
});
another way to show the hidden map when map is first time rendering the <div> is to set style: visibility.
When firstly hidden, use visibility = hidden; to show use visibility = visible
the reason is: visibility:hidden means that the contents of the element will be invisible, but the element stays in its original position and size.
this works fine for me, I use jquery tabs
setTimeout(function() {
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(default_lat, default_lng));
map.setZoom(default_map_zoom);
}, 2000);
om this link https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448
This will work
google.maps.event.addListener(map, "idle", function ()
{
google.maps.event.trigger(map, 'resize');
});
better way:
gmap.redraw = function() {
gmOnLoad = true;
if(gmOnLoad) {
google.maps.event.trigger(gmap, "resize");
gmap.setCenter(gmlatlng);
gmOnLoad = false;
}
}
and in show click event:
$("#goo").click(function() {
if ($("#map_canvas").css("display") == "none") {
$("#YMapsID").toggle();
$("#map_canvas").toggle();
if (gmap != undefined) {
gmap.redraw();
}
}
});
depending on what you are doing another posibility could be to have multiple bools you set to true when each process is done.
For example:
if you have a geocode service running which you want to wait for, you could have a var called
GeoState
and in the result part of the geocoder set GeoState to true,
then have a timed function check if all the services have returned true, when they have, make the map visible.
I have a Prototype snippet here that I really want to see converted into Mootools.
document.observe('click', function(e, el) {
if ( ! e.target.descendantOf('calendar')) {
Effect.toggle('calendar', 'appear', {duration: 0.4});
}
});
The snippet catches clicks and if it clicks outside the container $('calendar') should toggle.
Are you trying to catch clicks anywhere in the document? Maybe you could try...
var calendar = $('calendar');
$$('body')[0].addEvent('click', function(e) {
if (!$(e.target).getParent('#calendar')) {
var myFx = new Fx.Tween(calendar, {duration: 400});
myFx.set('display', 'block');
}
}
I'm not sure how you are toggling visibility but the way Fx.Tween.set works allows you to change any CSS property. You may want to look at http://mootools.net/docs/core/Fx/Fx.Tween for other possibilities.
Also, notice that I wrapped e.target using a $. This is specifically for IE. I wrote a post about this here under the sub-heading "Mootools Events Targets".
Lastly, I factored out $('calendar') so that you are not searching the DOM every time.