jQuery rotate spin - javascript

I have a problem with segment spin, in this spin wheel from https://www.sitepoint.com/jquery-wheel-fortune-demo/ demo: http://jsfiddle.net/sNYYD/237/
window.WHEELOFFORTUNE = {
cache: {},
init: function () {
console.log('controller init...');
var _this = this;
this.cache.wheel = $('.wheel');
this.cache.wheelMarker = $('.marker');
this.cache.wheelSpinBtn = $('.wheel'); //im using the wheel as the spin button but simply change this to a button if you want.
//mapping is backwards as wheel spins clockwise //1=win
this.cache.wheelMapping = [400, 120, 80, 750, 150, 300, 60, 175, 500, 125, 75, 1000, 120, 200, 90, 600, 100, 250].reverse();
this.cache.wheelSpinBtn.on('click', function (e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) _this.spin();
});
//reset wheel
this.resetSpin();
//setup prize events
this.prizeEvents();
},
spin: function () {
console.log('spinning wheel');
var _this = this;
// reset wheel
this.resetSpin();
//disable spin button while in progress
this.cache.wheelSpinBtn.addClass('disabled');
/*
Wheel has 10 sections.
Each section is 360/10 = 36deg.
*/
var deg = 1500 + Math.round(Math.random() * 1500),
duration = 6000; //optimal 6 secs
_this.cache.wheelPos = deg;
//transition queuing
//ff bug with easeOutBack
this.cache.wheel.transition({
rotate: '0deg'
}, 0)
.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 / 6)), //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);
//display dialog with slight delay to realise win or not.
setTimeout(function () {
alert('you won '+win+'!');
}, 700);
//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();
I have 18 segments and always the win number is wrong, Is the problem Math.ceil((percent / 6)) or this.cache.wheelPos = 0; ?
Thank you

I've been tempted to vote this question as duplicated...(see link)
I think your code lacks consistency: in one line there is a comment about having 10 segments, in other one you say 6, but it seems you have 18 different segments in your wheel. Fix that part (use constants!) and I think most of your issues will be solved.
UPDATED: The way you calculate the segment is incorrect, changing it with this solves the issue.
//the segment is 18 multiplied by the proportion
segment = Math.ceil((percent *18/100))-1;

Related

Phaser 3, No collisions between bullets and tilemap

According to the Phaser 3 examples I've created a tilemap from JSON file and added firing bullets with a left mouse clicking in a cursor's direction. Also a platform was added. My problem is that there are no collisions detected between a bullet and a tilemap's objects. But collisions work fine between the bullet and a platform.
Here is my demo code:
var config = {
type: Phaser.CANVAS,
width: 800,
height: 600,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create
}
};
var game = new Phaser.Game(config);
var bullets;
var platforms;
function preload ()
{
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/impact-tilemap.json');
this.load.image('kenney', 'assets/tilemaps/tiles/kenney.png');
this.load.image('ground', 'src/games/firstgame/assets/platform.png');
this.load.image('bullet', 'src/games/firstgame/assets/star.png');
}
function create ()
{
var map = this.make.tilemap({ key: 'map' });
var tileset = map.addTilesetImage('kenney');
var layer = map.createStaticLayer(0, tileset, 0, 0);
layer.setCollisionByExclusion([-1]);
this.physics.world.bounds.width = layer.width;
this.physics.world.bounds.height = layer.height;
platforms = this.physics.add.staticGroup();
platforms.create(400, 268, 'ground');
// Fires bullet on left click of mouse
this.input.on('pointerdown', function() {
fire(this);
}, this);
var Bullet = new Phaser.Class({
Extends: Phaser.GameObjects.Image,
initialize: function Bullet(scene)
{
Phaser.GameObjects.Image.call(this, scene, 0, 0, 'bullet');
this.speed = Phaser.Math.GetSpeed(300, 1);
this.velocity = new Phaser.Geom.Point(0, 0);
},
fire: function (x, y, direction)
{
this.setPosition(x, y);
this.setActive(true);
this.setVisible(true);
this.velocity.setTo(0, -this.speed);
Phaser.Math.Rotate(this.velocity, direction);
},
update: function (time, delta)
{
// Update position based on velocity
this.x += this.velocity.x * delta;
this.y += this.velocity.y * delta;
}
});
bullets = this.physics.add.group({
classType: Bullet,
maxSize: 30,
runChildUpdate: true
});
this.physics.add.collider(bullets, platforms, callbackFunc, null, this);
this.physics.add.collider(bullets, layer, callbackFunc, null, this);
}
function callbackFunc(bullet, target)
{
if ( bullet.active === true ) {
console.log("Hit!");
bullet.setActive(false);
bullet.setVisible(false);
}
}
function fire(that)
{
var bullet = bullets.get();
if (bullet) {
bullet.body.allowGravity = false;
var angle = Math.atan2(that.input.activePointer.y - 400, that.input.activePointer.x - 300);
bullet.fire(300, 400, angle + (3.14/2));
}
}
You can copy-paste it to any example at https://labs.phaser.io and start clicking to fire at any direction.
I've tried to add a standard player from examples too and collisions work fine with the tilemap's objects. So the problem is with bullets only.
Please help to solve this. Thanks!

Previous and next image link in JavaScript

I need help for the slider on TweenMax.js
The problem:
This example has 4 images, on click each images will open in a fullscreen.
But i am not getting the previous screen link and next screen link in fullscreen.
Expected Result: once image is clicked, it should get previous image hyperlink and next hyperlink in all the sliders
Please Note : Now it is working for last image and first image.
even though i click any image
Please accept my apologies, CODE is very big !
JSFIDDLE :
http://jsfiddle.net/goo08gg5/11/
Any help is appreciated, thanks in advance.
UPDATE:
I feel this place in JS, we need to make the changes, but i might be wrong
//next image link
TweenLite.set($expander_nav.last(), {
x : 160,
right : 4,
left : 'auto',
delay : delay
});
//first image link
TweenLite.set($expander_nav.first(), {
x : -160,
left : 4,
right : 'auto',
delay : delay,
onComplete : function () {
// add content to title overlay after delay
$title.html(self.$cur_circle.siblings('.tagline').html());
}
});
JAVASCRIPT
var HeroCircles = function(el) {
this.$el = $(el);
this.$circles = this.$el.find('.circle');
this.$expander = this.$el.find('.circle-expander');
this.$cur_circle = null;
};
HeroCircles.prototype._placeBG = function() {
// get parent position and dimensions
var self = this,
parent_pos = this.$el.offset(),
parent_width = this.$el.width(),
parent_height = this.$el.height();
this.$circles.each(function() {
var $circle = $(this),
offset = $circle.offset(),
$bg = $circle.children('.bg');
// set position
$bg.css({
'top': parent_pos.top - offset.top + 'px',
'left': parent_pos.left - offset.left + 'px',
'width': parent_width + 'px',
'height': parent_height + 'px'
});
});
};
HeroCircles.prototype._animateInTitle = function(delay) {
var self = this,
$title = this.$expander.children('.title-overlay'),
cur_class = this.$cur_circle.data('name'),
$expander_nav = this.$expander.children('.expander-nav').children('a').not('.' + cur_class);
TweenLite.set($expander_nav.last(), { x: 160, right: 4, left: 'auto', delay: delay });
//Last image
TweenLite.set($expander_nav.first(), {
x: -160,
left: 4,
right: 'auto',
delay: delay,
onComplete: function() {
// add content to title overlay after delay
$title.html(self.$cur_circle.siblings('.tagline').html());
}
});
//Firstimage
// animate in title overlay
TweenLite.to($title, 0.5, {
y: 40,
delay: delay,
ease: Back.easeOut
});
TweenLite.to($expander_nav, 0.15, {
x: 0,
delay: delay + 0.5
});
};
HeroCircles.prototype._animateOutTitle = function() {
var $title = this.$expander.children('.title-overlay'),
cur_class = this.$cur_circle.data('name'),
$expander_nav = this.$expander.children('.expander-nav').children('a').not('.' + cur_class);
// animate out title overlay
TweenLite.to($title, 0.5, {
y: $title.outerHeight()
});
// animate out circles
TweenLite.to($expander_nav.first(), 0.15, {
x: -160
});
TweenLite.to($expander_nav.last(), 0.15, {
x: 160
});
};
HeroCircles.prototype._animateIn = function(circle) {
var $circle = $(circle),
$border = $circle.siblings('.border'),
img = $circle.children('.bg').data('bg');
// set current circle
this.$cur_circle = $circle;
// set bg image for expander div
this.$expander.css('z-index', 4);
this.$expander.children('.bg').css('background-image', 'url(' + img + ')');
// add active class to li
$circle.parent('li').addClass('active');
// expand circle
TweenLite.to($border, 0.3, {
scale: 7
});
// fade in expander
TweenLite.to(this.$expander, 0.5, {
opacity: 1,
delay: 0.5,
onComplete: function() {
TweenLite.set($border, { scale: 1 });
}
});
// animate in title overlay
this._animateInTitle(1);
};
HeroCircles.prototype._animateOut = function() {
var self = this;
// remove active class and scale down border
this.$el.find('li').removeClass('active');
// animate out title
this._animateOutTitle();
// fade out expander
TweenLite.to(this.$expander, 0.5, {
opacity: 0,
delay: 0.5,
onComplete: function() {
self.$expander.css({
'z-index': -1
});
}
});
};
HeroCircles.prototype._animateSwitch = function(circle) {
this._animateOutTitle();
this.$cur_circle = $(circle);
var img = this.$cur_circle.children('.bg').data('bg'),
$bg = this.$expander.children('.bg');
// switch active class
this.$el.find('li').removeClass('active');
this.$cur_circle.parent('li').addClass('active');
TweenLite.to($bg, 0.3, {
opacity: 0,
delay: 0.5,
onComplete: function() {
$bg.css('background-image', 'url(' + img + ')');
TweenLite.to($bg, 0.3, { opacity: 1 });
}
});
this._animateInTitle(1);
};
HeroCircles.prototype.init = function() {
var self = this;
this._placeBG();
// add click events
this.$el.on('click', '.circle', function() {
self._animateIn(this);
});
this.$el.find('.close-btn').on('click', function(e) {
e.preventDefault();
self._animateOut();
});
this.$expander.children('.expander-nav').on('click', 'a', function(e) {
e.preventDefault();
var new_class = $(this).attr('class'),
$circle = self.$el.find('ul .' + new_class);
console.log("new class is", new_class, "new circle is", $circle[0]);
self._animateSwitch($circle);
});
};
HeroCircles.prototype.initMobile = function() {
var self = this,
$mobile_slider = this.$el.find('.mobile-slider');
this.$el.on('click', '.circle', function() {
var $this = $(this),
bg = $this.children('.bg').data('bg');
self.$circles.removeClass('active');
$this.addClass('active');
$mobile_slider.html('<div>' + $this.siblings('.tagline').html() + '</div>');
$mobile_slider.css('background-image', 'url(' + bg + ')');
});
this.$circles.first().trigger('click');
};
var hero_circles = new HeroCircles('.hero-circles');
if ( window.innerWidth > 580 ) {
hero_circles.init();
} else {
hero_circles.initMobile();
}
I have make
Expected Result: once image is clicked, it should get previous image
hyperlink and next hyperlink in all the sliders
But i dont know how work this fadeIn and fadeOut circle.
This script work fine for next and prev slide, but the animation slide is no good. but it's work !
I have add a index of clicked circle for next and prev slide.
please see: http://jsfiddle.net/gw4eqg92/

JavaScript Greensock loop not working as expected

Does anyone have any ideas why this is not working? Seems to hit the first background but then does not change position.
// Avatar animations
var fadePulse = true; // true: will fade avatar images and pulse in and out once changed
// false: will slide the avatars in and out
var avatarCount = 5; // set the amount of avatars in the sprite image
var avatarSpeed = 2 // set the avatar transition speed
var avatarHeight = 250; // set the height of a single avatar image
var avatars = creative.avatars;
var animDuration = 0.4;
var avatarCurrentIndex = 0;
var avatarAni = new TimelineLite({ paused: true, repeat: -1 });
function startAvatarAnimation() {
show(avatars);
avatarAni.to(avatars, animDuration, {
scaleX: 1, // 1.1 (for bouncing)
scaleY: 1, // 1.1 (for bouncing)
ease: Power3.easeIn,
onComplete: onCompleteScaleIn
});
avatarAni.to(avatars, animDuration, {
scaleX: 1,
scaleY: 1,
ease: Power3.easeOut
});
avatarAni.timeScale(avatarSpeed);
avatarAni.play();
}
function onCompleteScaleIn() {
avatarCurrentIndex ++;
console.log(avatarCurrentIndex ++);
if(avatarCurrentIndex <= avatarCount-1){
TweenLite.set(avatars, {
backgroundPosition: '0 -' + (avatarCurrentIndex * avatarHeight) + 'px'
});
} else {
avatarAni.pause();
hide(avatars);
}
}
It all seems to work apart from that part with looping through and adjusting the position.
// Avatar animations
var fadePulse = true; // true: will fade avatar images and pulse in and out once changed
// false: will slide the avatars in and out
var avatarCount = 5; // set the amount of avatars in the sprite image
var avatarSpeed = 2 // set the avatar transition speed
var avatarHeight = 250; // set the height of a single avatar image
var avatars = creative.avatars;
var animDuration = 0.4;
var avatarCurrentIndex = 0;
var i = 0;
var avatarAni = new TimelineMax({ paused: true, repeat: -1 });
function startAvatarAnimation() {
show(creative.avatars);
avatarAni.to(avatars, animDuration, { scaleX: 1, scaleY: 1, ease: Power3.easeIn, onComplete: onCompleteScaleIn });
avatarAni.to(avatars, animDuration, { scaleX: 1, scaleY: 1, ease: Power3.easeOut });
avatarAni.timeScale(avatarSpeed);
avatarAni.play();
}
function onCompleteScaleIn() {
i++;
if(i <= avatarCount-1){
TweenMax.set(avatars, { backgroundPosition: '0 -' + (i * avatarHeight) + 'px' });
} else {
avatarAni.pause();
hide(avatars);
}
}

How can I animate a smile into a frown by clicking on a button?

How can i morph an image by clicking on a button? This is a schools assignment. I need to draw a smile (which i did) and animate the smile into a frown by clicking on a button.
My prof told us to "Create a drawMouth function that takes 2 arguments, bx and by, and sets the mouth path using the values passed in. Call the function in your button event listener."
Apart from not understanding his instruction, i am also 100% sure that he did not teach animations yet!! So far the button I created can toggle between the smile and frown, but i have no idea how to make the animation.
var paper = new Raphael(document.getElementById("mySVGCanvas"));
// smile
var smile1 = paper.path("M 300,200 Q 400,300 500,200 Z");
smile1.attr({
'stroke': "blue",
'stroke-width': 5
});
// button
var button1 = paper.circle(100, 300, 50);
button1.attr({
'fill': "#c64ee4",
'stroke':"#c64ee4",
'stroke-width': 1
});
//0=success & smile, 1=rage & frown
var myState = 0;
//toggle
button1.node.addEventListener('click', function(){
console.log("this part is working...");
if (myState === 0){
myState = 1;
//toggle image
var image1 = paper.image("https://tromoticons.files.wordpress.com/2012/11/y-u-no.png?w=350&h=300&crop=1", 10, 10, 100, 100);
//toggle smile-frown
smile1.attr({
path: "M 300,200 Q 400, 100 500, 200 Z"
});
} else{
myState = 0;
//toggle image
var image1 = paper.image("http://www.sherv.net/cm/emoticons/trollface/success-troll-smiley-emoticon.png", 10, 10, 100, 100);
//toggle smile-frown
smile1.attr({
path: "M 300,200 Q 400,300 500, 200 Z"
});
}
});
You can create an animation with the javascript setInterval(...) function. This function executes code at a given time interval until it's terminated.
I.E. something like :
//toggle
var myInterval;
var theTime = 0;
var endTime = 1000;
button1.node.addEventListener('click', function(){
//toggle image
var image1 = paper.image("https://tromoticons.files.wordpress.com/2012/11/y-u-no.png?w=350&h=300&crop=1", 10, 10, 100, 100);
//toggle smile-frown
myInterval = setInterval(function() {
smile1.attr({
var smilePercent = myState === 1 ? theTime / endTime : 1 - theTime / endTime;
// here set your 'path' attribute as a function of 'smilePercent'
});
theTime += 50;
if (theTime >= endTime) {
theTime = 0;
clearInterval(myInterval);
}
}, 50);
myState = myState === 1 ? 0 : 1;
}
});

jquery animate step has incorrect start value

I'm having trouble performing a simple rotation animation using jquery's animate method. I am trying to start a square at 45 degrees rotation and then, when clicking a button, rotate the square another 45 degrees (to complete at 90).
However, when I attempt the animation, the square first jerks back to a rotation of 0 before starting to progress towards its final completion point (90 degrees).
This appears to be because the "now" argument of animate()'s "step" option is starting at 0, rather than the actual starting point of the element, 45 degrees.
Any thoughts on what I'm doing wrong here?
http://jsfiddle.net/agentfitz/btz89/2/
// css
.square {
transform: rotate(45deg); // starting point
}
// js
$(".square").animate(
{
rotation: 90,
},
{
step: function(now, tween) {
var $el = $(this);
if (tween.prop === "rotation") {
console.log(now);
$el.css('transform','rotate('+now+'deg)');
}
},
duration: 2000
}
);
Please follow this example: http://jqversion.com/#!/1GLob7P
Javascript code:
$("a").click(function(e){
e.preventDefault();
var initRotation = 0;
$(".square").animate(
{
rotation: 45, // how many degrees do you want to rotate
},
{
start: function(promise){
initRotation = getRotationDegrees($(this));
},
step: function(now, tween) {
var $el = $(this);
if (tween.prop === "rotation") {
var newRotation = initRotation + now;
$el.css('-webkit-transform','rotate('+newRotation+'deg)');
$el.css('-moz-transform','rotate('+newRotation+'deg)');
$el.css('transform','rotate('+newRotation+'deg)');
}
},
duration: 2000
}
);
});
function getRotationDegrees(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if(matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
} else { var angle = 0; }
return (angle < 0) ? angle +=360 : angle;
}
You can use start option to customize property start value:
// css
.square {
transform: rotate(45deg); // starting point
}
// js
var startRotation = 45;
$(".square").animate(
{
rotation: 90,
},
{
start: function(promise) {
for (var i = 0; i < promise.tweens.length; i++) {
var tween = promise.tweens[i];
if (tween.prop === "rotation") {
tween.start = startRotation;
}
}
},
step: function(now, tween) {
var $el = $(this);
if (tween.prop === "rotation") {
console.log(now);
$el.css('transform','rotate('+now+'deg)');
}
},
duration: 2000
}
);

Categories