Animate Element and make it drag&droppable - javascript

I am making a game, where a few products are flying one after another from right to left. The whole time they should also be draggable and be dropped to a certain position. But while dragged, they should not be animated, of course.
The code I have so far, animates the element, while dragging:
var animateElement = function(currentIndex) {
var endpoint = 20000;
$('.product-' + currentIndex.toString()).draggable();
$('.product-' + currentIndex.toString()).transition({
x: -600,
y: 100,
}, endpoint, "linear",
function() {
stopAnimation(currentIndex);
}
); //END ANIMATION
$('#dropProducthere').droppable({
accept: '.product-' + currentIndex.toString()
}); //END droppable
}
var stopAnimation = function(currentIndex) {
$('.product-' + currentIndex.toString()).stop().transition();
}
Is there a better solution than my one above?

Related

Is there a way to get the mouse coordinates with respect to page on mouseOver of a point in Highcharts?

I am trying to have a highchart spline chart with tooltip positioned to the right corner and have another tooltip on mouseover specific points. So basically I would like to show Two tooltips for some points. So far i was able to do that only on click event where we the event information with mouse coordinates with respect to page. Is there a way we can show two tooltips for same point? I want one tooltip to be positioned at the right corner and the other one next to the point as shown in the below JSfiifle.
"point": {
"events": {
"mouseOver": function(e) {
var selectedPoints = $('#' + this.series.chart.renderTo.id).highcharts().getSelectedPoints();
if (selectedPoints.length) {
selectedPoints[0].select();
}
if (e.target.marker && !e.target.marker.radius) {
return;
}
},
"mouseOut": function(e) {
util.hideBandInsightsPopup();
},
"click": function(e) {
if (e.point && e.point.marker && !e.point.marker.radius) {
return;
}
$("#factor-popup-content").html("my popup content");
var yPixel = e.pageY + 5;
var currentPointHeight = yPixel + $("#factor-popup").height();
if ($("#factor-popup").height() < 300 && currentPointHeight > $(window).height()) {
var adjustHeight = currentPointHeight - $(window).height() + 30;
yPixel = yPixel - adjustHeight;
}
$("#factor-popup").css({
'position': 'fixed',
'top': (yPixel) + 'px',
'left': (e.pageX) + 5 + 'px'
}).show();
}
}
}
Here is the Jsfiddle http://jsfiddle.net/zLpakfj2/4/
The original event is not passed to the mouseOver event, but you can add it for example to a point in this way:
(function(H) {
H.wrap(
H.Pointer.prototype,
'getHoverData',
function(
proceed,
existingHoverPoint,
existingHoverSeries,
series, isDirectTouch,
shared,
e
) {
var result = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
if (result.hoverPoint) {
result.hoverPoint.originalEvent = e;
}
return result;
});
}(Highcharts));
Live demo: http://jsfiddle.net/BlackLabel/y18h30t4/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts

Snap SVG animation slowing down the FPS

As you can see on this page: http://www.gigil.it/newroot/index.php//come-doniamo
I have some svg animations done with snap SVG.
The animations are triggered when the element is in the viewport.
And it's basically doing the same animation on all the paths inside the SVG.
Here is the script:
jQuery(window).scroll(function() {
jQuery(".icon-come-doniamo").each(function(){
//console.log($(this));
if (jQuery(this).isOnScreen() == true) {
if (!jQuery(this).hasClass("already-visible")){
var $that = jQuery(this);
setTimeout(function(){
//jQuery(this).addClass("already-visible");
var Elemento = $that.find("svg");
var iconSnap = Snap("#"+Elemento.attr("id"));
var iconPaths = iconSnap.selectAll("path");
var delays = 0;
var count = 0;
iconPaths.forEach(function(elem,i) {
setTimeout(function(){
//console.log("gegge");
var elemDim = elem.getBBox();
elem.animate({transform: 'r0,' + elemDim.cx + ',' + elemDim.cy + 's1,1' }, 700, mina.linear );
}, delays);
delays = delays + 400;
count = count + 1;
});
if (count == iconPaths.length) {
//console.log("fattgegge");
$that.addClass("already-visible");
}
},1000);
}
}
});
});
Pretty simple I think, but very often the FPS gets really really low and the animations become super bulky.
I've tried anything, but no big changes.
Any tips?
Solved it by removing the Bounding Box calculations.
Removed the rotation property.
Now it's a lot smoother.
From this:
elem.animate({transform: 'r0,' + elemDim.cx + ',' + elemDim.cy + 's1,1' }, 700, mina.linear );
to this:
elem.animate({transform: 's1,1' }, 700, mina.linear );

jQuery spin function - specify 20% spin upon image click?

I'm a jQuery newbie - but have managed to modify a roulette wheel script to spin a "pie" image for a homepage I'm working on.
It works great - but the client also want to add an arrow on either side that will advance the pie one section upon click - so clockwise for one arrow, counter-clockwise for another.
Is there a way to specify a partial spin?
Any guidance is much appreciated! I'm trying to meet a ridiculous deadline and am struggling with this.
Here's the page:
http://bluetabby.com/rr/index13.html
Here's the jQuery code so far - the functions I need to figure out are leftArrow and rightArrow:
$( document ).ready(function() {
window.WHEELOFFORTUNE = {
cache: {},
init: function () {
console.log('controller init...');
var _this = this;
this.cache.wheel = $('.wheel');
this.cache.wheelSpinBtn = $('.wheel');
this.cache.leftArrow = $('.leftarrow');
this.cache.rightArrow = $('.rightarrow');
//mapping is backwards as wheel spins clockwise //1=win
this.cache.wheelMapping = ['Mitzvahs','Galas','Florals','Props','Weddings'].reverse();
this.cache.wheelSpinBtn.on('load', function (e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) _this.spin();
});
this.cache.rightArrow.on('click', function (e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) _this.spin();
});
},
spin: function () {
console.log('spinning wheel');
var _this = this;
//disable spin button while in progress
this.cache.wheelSpinBtn.addClass('disabled');
/*
Wheel has 10 sections.
Each section is 360/10 = 36deg.
*/
var deg = 1000 + Math.round(Math.random() * 1000),
duration = 6000; //optimal 6 secs
_this.cache.wheelPos = deg;
//transition queuing
//ff bug with easeOutBack
this.cache.wheel.transition({
rotate: '0deg'
}, 0).delay(1000)
.transition({
rotate: deg + 'deg'
}, duration, 'easeOutCubic');
//move marker
_this.cache.wheelMarker.transition({
rotate: '-20deg'
}, 0, 'snap');
//just before wheel finish
setTimeout(function () {
//reset marker
_this.cache.wheelMarker.transition({
rotate: '0deg'
}, 300, 'easeOutQuad');
}, duration - 500);
//wheel finish
setTimeout(function () {
// did it win??!?!?!
var spin = _this.cache.wheelPos,
degrees = spin % 360,
percent = (degrees / 360) * 100,
segment = Math.ceil((percent / 5)), //divided by number of segments
win = _this.cache.wheelMapping[segment - 1]; //zero based array
console.log('spin = ' + spin);
console.log('degrees = ' + degrees);
console.log('percent = ' + percent);
console.log('segment = ' + segment);
console.log('win = ' + win);
//re-enable wheel spin
_this.cache.wheelSpinBtn.removeClass('disabled');
}, duration);
},
resetSpin: function () {
this.cache.wheel.transition({
rotate: '0deg'
}, 0);
this.cache.wheelPos = 0;
}
}
window.WHEELOFFORTUNE.init();
});//]]>
Thanks for any pointers!
I looked through your code and figured out you are using transit.js to do the spinning animations. Essentially, the object's css (transform "rotate") is being updated over a certain amount of time (like jQuery's animate).
You can extend your wheel of fortune object with spinright and spinleft functions (or whatever name you prefer), which you can bind to the keys/buttons that you'll create. Your code would look something like this:
WHEELOFFORTUNE.spinright = function() {
// get current degree of wheel and convert to integer
var degree = parseInt( this.cache.wheel.css('rotate'), 10 );
this.cache.wheel.transition( { "rotate": (degree + 73) + "deg" },1000 );
}
WHEELOFFORTUNE.spinleft = function() {
var degree = parseInt( this.cache.wheel.css('rotate'), 10 );
this.cache.wheel.transition( { "rotate": (degree - 73) + "deg" },1000 );
}
Then you can bind these functions to buttons or call the functions directly in console:
WHEELOFFORTUNE.spinright()
WHEELOFFORTUNE.spinleft()
Note: 73deg looks to be about the amount that 1 section is, but you'll probably have to play around with the numbers. You may also want to cache the degrees in your object as well. You probably will also need to figure out a way to center on each section per button press.
Cheers!

greensock draggable / triggering click and drag

I have an issue which is related to greensock animation but also may be a more general js issue in that I need to transfer a mousedown event to a second draggable instance after killing the first draggable instance.
the codepen hopefully will illustrate what i am trying to do.. code is underneath.
Codepen URL: http://codepen.io/anon/pen/ypdGn
var detachdraggable;
var rotatedraggable;
function makeRotateDraggable() {
// create rotate draggable for the cards..
rotatedraggable = Draggable.create(".dragclone", {
type:"rotation",
throwProps:true,
dragResistance : 0,
edgeResistance : 1,
bounds:{minRotation:-60, maxRotation:60},
onDragStart : function() {
var $el = $(this.target);
var cardStartAngle = $el.data('startangle');
},
onDrag: function() {
currentCardAngle = this.rotation;
var $el = $(this.target);
var cardStartAngle = $el.data('startangle');
cardDirection = ( currentCardAngle > cardStartAngle ) ? "up":"down";
cardTravelDegrees = Math.abs(currentCardAngle - cardStartAngle);
this.vars.type = "x";
},
onDragEnd: function() {
},
onClick: function() {
return false;
}
});
$('.dragclone').mousedown(function() {
$('.dragclone').css('z-index','10');
rotatedraggable[0].enable();
});
$('.dragclone').mouseout(function() {
detachdraggable[0].disable();
$('.dragclone').trigger('mousedown');
});
$('.dragclone').trigger('mouseout');
}
// first setup the x,y draggable..
detachdraggable = Draggable.create('.dragclone', {
type: "x,y",
edgeResistance:1,
throwProps:true,
onPress:function() {
startX = this.x;
startY = this.y;
},
onDrag:function() {
var xChange = this.x - startX,
yChange = this.y - startY,
ratio = Math.abs(xChange / yChange),
direction = [];
// NB:: you can adjust these ratio thresholds to make things
// more or less sensitive to diagonal movement.
if (ratio > 0.25) {
direction.push((xChange < 0) ? "left" : "right");
}
if (ratio < 4) {
direction.push((yChange < 0) ? "up" : "down");
}
if(direction[0] == "left") {
// TweenMax.to( $('.cloned'), .0001, {right:-xChange + 135});
}
// moving up so lets switch cards !!
if(direction[0] == "up") {
if(Math.abs(yChange) > 20) {
makeRotateDraggable();
}
}
},
onDragEnd:function() {
// driftDragCardBack();
// if(!cardPopping) { driftClonedCardBack(); }
},
onThrowComplete: function() {
}
});
I am battling to switch between 2 draggables setup on same element, am wondering if this is possible at all. basically the codepen has an example of what I want to do, but it isnt seamless. draggable is setup for element of type x,y, what i want to do is when the drag direction is up kill the type x,y draggable and switch to a type: rotation draggable so that the card moves around on an axis. you can see mine does that, but only if you release and then click again - is there any way to make this seamless, so it just switches mid-drag ?
thanks,
Justin
See http://codepen.io/anon/pen/klanu
I've never used greensock but just had a look at their document:
https://greensock.com/docs/#/HTML5/Drag/Draggable/startDrag/
First of all you had a couple of issues within your code. You don't need to create rotatedraggable inside a function, just create it, it's not enabled anyways. I also moved
$('.dragclone').mousedown(function() {
$('.dragclone').css('z-index','10');
detachdraggable[0].enable();
});
outside the function.
In your 2nd draggable, you were calling createRotation to create the rotation but like I said you can create it at the start. When the div is moved to the top, I just disabled the current drag and enabled the 1st one and called dragStart on it. e is what's passed to drag of the 2nd.
if(Math.abs(yChange) > 20) {
detachdraggable[0].disable();
rotatedraggable[0].enable();
rotatedraggable[0].startDrag(e);
}

Trail effect with jQuery?

Can this be done ? Basically I want to animate an absolute-positioned image with right:xxxPX, let's say. Well, when the animation is in progress, can I add a "trail" effect to it?
Thanks,
Adrian
This should work:
var box = $('#box'),
// Create some clones (these make up the trail)
clones = $.map(Array(10), function(item, i){
return box.clone().css('opacity', 1 / (i + 1)).hide().insertAfter(box);
});
box.animate({
top: 100,
left: 200
}, {
duration: 1000,
step: function(now, fx) {
// On each step, set a timeout for each clone,
// making it move to the required position.
var prop = fx.prop;
$.each(clones, function(i, clone){
clone = $(clone).show();
setTimeout(function(){
clone.css(prop, now);
}, 50 * i);
});
}
});
Demo: http://jsbin.com/ifobe3

Categories