Git Product home page Git Product logo

javascript-winwheel's People

Contributors

lorisz avatar zarocknz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

javascript-winwheel's Issues

resetWheel examples change the rotation of the wheel to zero degrees

In many of the examples, when you press the "Reset wheel" button, this occurs:

theWheel.rotationAngle = 0;

Which unfortunately looks bad, as the wheel resets to its original rotation.

In order to maintain the current position of the wheel when reset, instead of changing the rotation value to "0", it should be like this instead:

theWheel.rotationAngle = theWheel.rotationAngle % 360;

This should allow it to continue animating properly, while maintaining the current rotation.

Callback when a segment or pin passes the pointer

A few people have contacted me about how to play a click sound when the edge of a segment passes the pointer, this is also what the pins are supposed to be for but I could never get it to sound right.

Re-look in to the audio thing and at the very least add some way for code to know when the edge of a segment or a pin has passed the pointer so - something - can be done with that, such as play a sound.

Figure out the sound thing later, perhaps leave it up to the developer as they may want to use the audio API or a canned audio file.

If get it working then add a tutorial on this.

Setting the Prize to be won before spinning

Hi, first of all I want to thank you for your work, is really great, the documentation is fantastic!
Now, I created a wheel and set the pointerAngle equal to 90 to put it on the right side of the wheel, I use the pointerGuide helper to check it and everythings is ok.
The issue comes when i set an stopAngle using the getRandomForSegment() this stop the wheel in the segment i want but pointing to the top, so the getIndicatedSegment() shows me an incorrect information and the pointer is pointing the incorrect segment.
I've read all the documentation to check if there's an option to set the final direction of the selected segment to be at the same direction of the pointerAngle and I couldn't find a solution. Maybe I miss something.

If you can help me with this I would appreciate it greatly.

Thank you

Each segment to have its own probability to land

Hello Doug!

This is the wheel I've been searching for days and finally found it. This is working great on every browser and almost all devices I've tested. One thing I'm looking forward to have in this is a probability value for each segment. So, that I can offer expensive gifts in a low probable segment and cheaper prices in high probable segments.

Is this doable with your WinWheel ?

Thanks again!
Tharindu

Predetermined Winning & Segments Images

This plugin looks awesome but I have a few questions that I can't seem to figure out.

  1. I'd like to use PHP to predetermine a winning segment, then have the wheel spin randomly and land on that winner. Would this be possible with this plugin?

  2. I'd like to show little thumbnails of images instead of segment names. Would this be possible as well?

Thanks for the help ๐Ÿ™

The lineWidth doesn't seem to be working

It's either on or off

canvasId: 'lumifish-wheel', numSegments: 24, outerRadius: outerRadius, innerRadius: innerRadius, textFontFamily: '\'Roboto\', sans-serif', textFontSize: 22, textFontWeight: '900', textAlignment: 'outer', fillStyle: '#fff', textFillStyle: '#fff', lineWidth: 15, // ain't doing nothin'

Now what's up with that?

Secondly, why can't I have just an outline around the wheel, but ignore the inner outline for the segments?

I kinda need the pins to be sitting out on the white outline around the wheel.

Highlight When Spin is Finish

Hi @zarocknz ,

Can i highlight area of winner segment? Or does plugin have function / option to show where a winner segment?

Maybe like this picture :

screen shot 2017-12-28 at 10 53 01

I want WinWheel highlight winner segment to notify the user.

Thank you ๐Ÿ˜ƒ

Winwheel.js segments and array

Hi, I first and foremost wanted to thank you for making this script and tutorial easy to comprehend and follow. I had one question about the segments: what I want to do with my wheel is to have each segment open up random pages that relates to each segment. So for example, I have 5 segments on my wheel, and I want my "lets play a game!" Segment to open up random html pages that have games on it, and I want my "lets eat!" Segment to open up random html pages that have recipes, etc. I would like to know how to assign each segment a certain array of pages, and have them correspond to each segment.

how to make pins responsive?

any ideas? I got the wheel responsive by using bootstrap, and a call to the resizeCanvas() function supplied by one of the commenters - but getting the pins to scale seems to be beyond me.
any help appreciated.
thanks

Reverse rotation problem

var firstWheel=new Winwheel({
'canvasId' : 'firstcanvas',
'outerRadius' : 170,
'numSegments' : 10,
'innerRadius' : 5,
'textFontSize' : 55,
'textOrientation' : 'vertical',
'textFontFamily' : 'Courier',
'textAlignment' : 'outer',
'textFillStyle' :'#ffffff',
'strokeStyle' :'#ffff00',
'textMargin' : 5,
'segments' :
[
{'fillStyle' : '#ff0000', 'text' : '1'},
{'fillStyle' : '#000000', 'text' : '2'},
{'fillStyle' : '#ff0000', 'text' : '3'},
{'fillStyle' : '#000000', 'text' : '4'},
{'fillStyle' : '#ff0000', 'text' : '5'},
{'fillStyle' : '#000000', 'text' : '6'},
{'fillStyle' : '#ff0000', 'text' : '7'},
{'fillStyle' : '#000000', 'text' : '8'},
{'fillStyle' : '#ff0000', 'text' : '9'}
],
'lineWidth' : 3,
'animation' :
{
'type' : 'spinToStop',
'duration' : 45,
'spins' : 60,
'callbackFinished' :'calculatePrizeOnServer1()',
'callbackAfter' : 'drawTriangle()',
'callbackSound' : 'playSound2()',
'soundTrigger' : 'pin'
},
'pins' :
{
'number' : 20,
'outerRadius' : 5,
'margin' : 5,
'fillStyle' : '#00ff00',
'strokeStyle' : '#ffffff'
}
});
var xhr1 = new XMLHttpRequest();
xhr1.onreadystatechange = ajaxStateChange1;
function calculatePrizeOnServer1(){
xhr1.open('GET',"calculate_price_first_digit.php", true);
xhr1.send('');
}
function ajaxStateChange1(){
if (xhr1.readyState < 4){
return;
}

        if (xhr1.status !== 200){
            return;
        }
 
        if (xhr1.readyState === 4){
            var segmentNumber1 = xhr1.responseText;

// segmentNumber1=4;
first_digit=segmentNumber1;

            if (segmentNumber1){
            	segmentNumber1=parseInt(segmentNumber1);
               var stopAt1 = firstWheel.getRandomForSegment(segmentNumber1);
               firstWheel.animation.stopAngle = stopAt1;
               firstWheel.startAnimation();

// highlight_segment(firstWheel,segmentNumber1);
}
else{
var stopAt1 = firstWheel.getRandomForSegment(10);
firstWheel.animation.stopAngle = stopAt1;
firstWheel.startAnimation();
// highlight_segment(firstWheel,10);

            }
        }
    }
 
	drawTriangle();
	function drawTriangle(){
        var ctx = firstWheel.ctx;
        ctx.strokeStyle = 'navy';    
        ctx.fillStyle   = 'aqua';     
        ctx.lineWidth   = 2;
        ctx.beginPath();             
        ctx.moveTo(190, 10);
        ctx.lineTo(190, 70);
        ctx.lineTo(200, 90);
        ctx.lineTo(210, 70);
        ctx.lineTo(210, 10);
        ctx.lineTo(190, 10);
        ctx.stroke();
        ctx.fill();
    }
	var audio2 = new Audio('sound/Tick.mp3');

    function playSound2(){

// audio2.pause();
audio2.currentTime = 0;
audio2.play();
}

the wheel reverse rotated. how to fix this problem. I need to spin only one direction and stop in the defined result segment. It stops in the correct segment but for finding segment it rotates reverse.

Winwheel.js getIndicatedSegment undefined

Hi, Thanks for the awesome job you've done on this plugin. I have not come across another js plugin for a lucky spinning wheel better than this one yet. I'm having an issue with the getIndicatedSegment property when calling the alert prize(); function in an Ionic 3/Angular 2 application. I've followed this issue https://stackoverflow.com/questions/44306571/how-to-use-winwheel-js-callback-in-angular2 and have gotten it to work with the app and spinning quite well.

When the alert prize function is called, I get this error:

TypeError: Cannot read property 'getIndicatedSegment' of undefined
at alertPrize (http://localhost:8100/?ionicplatform=ios:51:41)
at eval (eval at winwheelStopAnimation (http://localhost:8100/build/vendor.js:137240:13), :1:1)
at n.winwheelStopAnimation (http://localhost:8100/build/vendor.js:137240:13)
at n.callback (http://localhost:8100/assets/scripts/TweenMax.min.js:16:22797)
at n.
.render (http://localhost:8100/assets/scripts/TweenMax.min.js:14:4905)
at Object.n.render (http://localhost:8100/assets/scripts/TweenMax.min.js:16:27269)
at Object.O._updateRoot.D.render (http://localhost:8100/assets/scripts/TweenMax.min.js:16:31859)
at Object.n.dispatchEvent (http://localhost:8100/assets/scripts/TweenMax.min.js:16:19594)
at g (http://localhost:8100/assets/scripts/TweenMax.min.js:16:20122)

I've followed the advice in that answer and added the prize function in my index.html file in order to get access to the Prize callback that is in my page.ts file and show the alert on the basic example to alert the prize. However, when I am trying to access the getIndicatedSegment variable, I get this issue.

Here is the code in my LuckySpinPage.ts file:

export class LuckySpinPage {
constructor(public navCtrl: NavController) { }
wheel;
wheelSpinning = false;

	ngAfterViewInit() {
		this.initWheel();
	}

	initWheel() {
    	this.wheel = new Winwheel({
			'numSegments': 10,   // Specify number of segments.
			'outerRadius': 150,  // Set radius to so wheel fits the background.
			'innerRadius': 30,  // Set inner radius to make wheel hollow.
			'pointerAngle': 0,
			'pointerGuide': false,       // Turn pointer guide on.
			'drawMode' : 'segmentImage', 
			'segments': [
				{'image' : '../../assets/images/segment-winner.png'},
				{'image' : '../../assets/images/segment-1.png'},
				{'image' : '../../assets/images/segment-2.png'},
				{'image' : '../../assets/images/segment-3.png'},
				{'image' : '../../assets/images/segment-5.png'},
				{'image' : '../../assets/images/segment-6.png'},
				{'image' : '../../assets/images/segment-7.png'},
				{'image' : '../../assets/images/segment-8.png'},
				{'image' : '../../assets/images/segment-9.png'},
				{'image' : '../../assets/images/segment-10.png'}
			  ],			    
			  'animation':           // Define spin to stop animation.
		      {
		        'type': 'spinToStop',
		        'duration': 5,
		        'spins': 10,
			'callbackFinished': 'alertPrize()'
	      	}
	    });			
	}
  // -------------------------------------------------------
  // Click handler for spin button.
  // -------------------------------------------------------
  startSpin() {
    // Ensure that spinning can't be clicked again while already running.
    if (this.wheelSpinning === false) {
      this.wheel.startAnimation();
      this.wheelSpinning = true;
    }
}

}

The code in the index.html file:

<script> // This function called after the spin animation has stopped. function alertPrize(){ // Call getIndicatedSegment() function to return pointer to the segment pointed to on wheel. var winningSegment = this.wheel.getIndicatedSegment(); // Basic alert of the segment text which is the prize name. alert("You have won " + winningSegment.text + "!"); } </script>

My aim is to get the prize on a specific segment e.g alert you've won, when it lands on segment 4, or alert not prize won when landing on any other segment.

Responsive 2 part wheel

May I know how to make the 2 part wheel responsive together with the wheel background? I tried one of the suggestion on last issues but the inner wheel doesn't display when resizing, only theouter wheel is displayed. Thanks in advance.

Make segment images size fill the containing canvas

Hello.
Would it be possible to make the segment images full size even if the passed in image is too small?
'segments' : // Define segments including image and text.
[
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''},
{'image' : 'images/img.png', 'text' : ''}
],

Maybe a flag would be nice, like: scaleSegmentImages ?

Basically make the segment images fill the containing canvas size.
Thank you :)

Make all wheel modes responsive

Make all wheel modes responsive especially the 2 image modes, ensure images both scale up (will probably look bad but oh well) and also scale down.

Consider what options could be included in the constructor to make the wheel responsive, also what code does a developer have to add in to make this work.

Do a full tutorial on this with an example of each drawType (code, image, segmentImage) to test out.

After landing on a segment, remove ability to land on it again (by spin level)

Hi Doug!

Thank you so much for building this and releasing it into the wild! I've gone through most of the tutorials and have adapted the winwheel into a faux-chat roulette video selector using images in the spin wheel. Landing on an image pops the alert which then shows 2 hidden divs that play a simulated video chat.

What I'm trying to do now is make sure a viewer doesn't land on the same combination twice - I want them to cycle through all the video stories. I have 7 "people" and 3 spin levels, so 21 combinations of 42 total videos.

Do you have some suggestions for 'turning off' an image segment after it's been used so that the wheel doesn't land on it again? I want to do this by spin level.

Here's a look at my current wheel. As an example, if a viewer chooses the Truth or Dare spin level and the selector lands on Ryan, when they spin again, I don't want Ryan to be available to land on again. If on the next spin they land on Alan, I want Ryan + Alan to no longer be available for the following spins, until all 7 people are finished and they viewer moves on the the next spin level (or they can shift back and forth but I want to maintain the exclusions while they are in current session).

Maybe I need to drop a cookie to keep track? I'm just not sure how to go about this in an efficient way, so any help or insight is greatly appreciated!

Thank you,
Chris

wof-video-chat-roulette

More flexible text

It would be great to have html tags or at least text overflown to two lines.

How to use modal instead of alert?

Really loving the winwheel buddy; excellent script! One question, I have managed to completely customise the wheel and it looks great. I was just wandering if you could help with creating a custom modal instead of the AlertPrize{} function, and use the segment name as the model content?

Any help would be appreciated, as I am not an very good coder :)

Thanks!

SpinOngoing defaults not applied as expected

While looking in to a query on the SpinOngoing animation I discovered that the defaults as stated in the documentation are not being applied.

Namely the repeat and easing expected are -1 and Linear.EaseNone but because in the constructor of the winwheel 0 is specified for the repeat and power3.easeOut is defined for the easing these are not null so the defaults for the SpinOngoing type of animation are not applied.

Solution is probably to ensure that these are null in the constructor and are only set by a check of the animation type to the default if not specified in the parameters.

Calling stop animation errors unless animation has run before

Calling stop animation errors if the animation has not run before.

Issue is in WinwheelStopAnimation tries to kill the tween of the WinwheelToAnimate but if the animation has not run before the Winwheel to animate is null.

Add check that the wheel to animate exists before trying to make a call to kill the tween.

animation is very laggy on android

First of thanks for the amazing wheel library, it has everything anyone can imagine. ๐Ÿ‘

I used this in ionic app for mobile. I am facing one issue. the animation is so laggy on android & on iOS its good at lest its feels like spinning.

android version i have tested is 4.4

Is there anyway we can improve this?

Line width overlap

Thanks again for an amazing plugin!

Question, I have the lineWidth set to 10, and it applies the width correctly to the outer ring, but the inner segments are inconsistent stroke width wise (the center line segment is bigger than the others). Am I missing a setting? Just looking to have consistent stroke widths on all segments. I'm ok with the outer ring and the segments being different.

https://cl.ly/sJqw

Option for uploading center image (logo of the company may be) for hollow wheels (doughnuts)

Hi,

I am using wineheel.js for my project and I would like to have the option that my clients may upload their company logo and it will be set at the center of the wheel (of course if it's a hollow wheel). Now, can anybody please guide me how can I modify this library in order to have this feature? Because I don't think for now this library have this feature.

Regards,
Junaid

can't use it with vuejs [solved], turns out the npm package is broken.

got this error while using it on vuejs, even the data, etc been mapped to vue format..

installed the winwheel from npm package:
https://www.npmjs.com/package/winwheel

`

        <div class="wheel-wrapper">
            <div>
                <div class="power_controls">
                    <a href="#" @click.prevent="startSpin()">START</a>
                    <a href="#" @click.prevent="resetWheel()">Reset</a>
                </div>
            </div>
            <div width="438" height="582" align="center" valign="center">
                <canvas id="canvas" width="434" height="434">
                    <p style="{color: white}" align="center">Sorry, your browser doesn't support canvas. Please try
                        another.</p>
                </canvas>
            </div>
        </div>
</section>
` `<script> import Winwheel from 'winwheel'

export default {
name: 'LuckySpin',
data() {
return {
theWheel: new Winwheel({
numSegments: 8, // Specify number of segments.
outerRadius: 212, // Set outer radius so wheel fits inside the background.
textFontSize: 28, // Set font size as desired.
// 'pointerAngle': 90,
// Define segments including colour and text.
segments: [
{ fillStyle: '#eae56f', text: 'Prize 1' },
{ fillStyle: '#89f26e', text: 'Prize 2' },
{ fillStyle: '#7de6ef', text: 'Prize 3' },
{ fillStyle: '#e7706f', text: 'Prize 4' },
{ fillStyle: '#eae56f', text: 'Prize 5' },
{ fillStyle: '#89f26e', text: 'Prize 6' },
{ fillStyle: '#7de6ef', text: 'Prize 7' },
{ fillStyle: '#e7706f', text: 'Prize 8' }
],
// Specify the animation to use.
animation: {
type: 'spinToStop',
duration: 3, // Duration in seconds.
spins: 10, // Number of complete spins.
callbackFinished: this.onFinishSpin
}
}),
wheelPower: 1,
wheelSpinning: false
}
},
methods: {
startSpin() {

		if (this.wheelSpinning == false) {
			this.theWheel.animation.spins = 10

			var stopAt = 46 + Math.floor(Math.random() * 43)


			this.theWheel.animation.stopAngle = stopAt

			this.theWheel.startAnimation()
			this.wheelSpinning = true
		}
	},
	resetWheel() {
		this.theWheel.stopAnimation(false) // Stop the animation, false as param so does not call callback function.
		this.theWheel.rotationAngle = 0 // Re-set the wheel angle to 0 degrees.
		this.theWheel.draw() // Call draw to render changes to the wheel.
		this.wheelSpinning = false // Reset to false to power buttons and spin can be clicked again.
	},
	onFinishSpin(indicatedSegment) {
		console.log(indicatedSegment)
		alert(indicatedSegment.text)
	}
},
computed: {},
updated() {},
mounted() {},
created() {}

}
</script>`
image

Working With API's?

Hey this is not an issue with the code itself. It's more of a question on how to incorporate API's to show on the segments. I managed to insert the object within the array to the winwheel segments key:value pair but I still get errors as it does not load. I get Uncaught TypeError: Cannot read property 'fillStyle' of undefined.

I have a repo with all of my work but the code is not pretty. It is somewhat short though 200+ lines of code so hopefully you can just tell me what am I doing wrong and how I can make the data load from my Google Places API.

Here is the link to my repo

Thanks!

Issue with the segments of the wheel becomes overlapped when more segments are added

<script type="text/javascript" src="../js/jquery-3.3.1.min.js"></script> <script src="../js/bootstrap.min.js" ></script>
<!-- Plus Minus button -->

<link rel="stylesheet" href="../js/plusminusbutton/style.css" />
<script src="../js/plusminusbutton/script.js"></script>

<!-- Wheel of fortune -->
<script src="../js/javascript-winwheel-2.7.0/Winwheel.js" ></script>
<script src="../js/javascript-winwheel-2.7.0/TweenMax.min.js"></script>

<!-- Toggle Switch -->
<link href="../css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="../js/bootstrap-toggle.min.js"></script>

<!-- Datatable -->
<link rel="stylesheet" href="../css/dataTables.bootstrap4.min.css">
<script src="../js/jquery.dataTables.min.js" ></script>
<script src="../js/dataTables.bootstrap4.min.js" ></script>
<script src="../js/dom-text.js" ></script>

<style>
    

    hr {
        margin-top: 1rem;
        margin-bottom: 1rem;
        border: 0;
        border-top: 2px solid rgba(0, 0, 0, 0.1);
    }

#canvasContainer {
position: relative;
width: 300px;
height:0;
}

#canvas {
z-index: 1;
}

#prizePointer {

 position: absolute;
 left: 175px;
 top: -12px;
 z-index: 999;

}
#wheelSpinner {

position: absolute;
left: 150px;
top: 150px;
cursor:pointer;
background-color:#DAA520

}
#wheelSpinner{
display: inline-block;
text-decoration: none;
background: gold;
color: #FFF;
font-size:3em;
width: 120px;
height: 120px;
line-height: 120px;
border-radius: 50%;
text-align: center;
font-weight: bold;
vertical-align: middle;
overflow: hidden;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.29);
border-bottom: solid 3px #bd6565;
transition: .4s;
}

#wheelSpinner:active{
-ms-transform: translateY(2px);
-webkit-transform: translateY(2px);
transform: translateY(2px);
box-shadow: 0 0 1px rgba(0, 0, 0, 0.15);
border-bottom: none;
}

#center {
position: absolute;

z-index: 15;
top: 50%;
left: 50%;
margin: -100px 0 0 -150px;
}
@media screen and (max-width: 600px) {
table.winner_list{
display:none;

}
table.winner_list{
    background:gold;
    position:fixed;
    z-index:999;
}
table.winner_list td{
    border-top:1px solid black;
}

}

@media only screen and (min-width:600px) {
.hide-on-desktop{
display: none;

}

}

.show_toggle:active table.winner_list{
    display:block;
}

.show_toggle:active .hide-on-desktop{
    display:none;
}

table.winner_list{

}
table.winner_list thead> tr >th{
background:gold;
color:black;
padding:20px;
letter-spacing: 3px;
}
table.winner_list tbody td {
border-bottom:2px solid gold;
color:green;
text-transform:uppercase;
font-style: oblique;
text-align:center;

}
body{
background: #d9a7c7; /* fallback for old browsers /
background: -webkit-linear-gradient(to right, #fffcdc, #d9a7c7); /
Chrome 10-25, Safari 5.1-6 /
background: linear-gradient(to right, #fffcdc, #d9a7c7); /
W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */

}

</style> <script> $(document).ready(function() {
    var theWheel=null;
    var dataZ=null;
        var table = $('#referalUserListTable').DataTable( {
            "columnDefs": [
                {
                    "targets": [3],
                    "orderDataType": "dom-text"
                
                },{
                    "targets": [0],
                    "orderable": false
                }
            ]
        } );

    updateWheel();
    updateWinnerList();
     $('.modal').on('hidden.bs.modal', function () {
        // location.reload();
        updateWheel();
        updateWinnerList();
    })

    

} );


function updateReferalTableWinner(userId_){
    
    $.ajax({
        type  : 'GET',
        url  : '../phpfunctions/luckydraw.php?',
        data : {updateReferalTableWinner:'true',userId:userId_},
        success: function (data) {
            
        },
        error: function(xhr, status, error) {
            console.log(error);
            
        }
    });
}

function updateReferalTable(userId_,str){
   
   var qty_=str.value;
   if(qty_>0)
    $.ajax({
        type  : 'GET',
        url  : '../phpfunctions/luckydraw.php?',
        data : {updateReferalTable:'true',userId:userId_,qty:qty_},
        success: function (data) {
            console.log(data);
            
        },
        error: function(xhr, status, error) {
            console.log(error);
            
        }
    });
   
}

function updateWheel(){
    $.ajax({
        type  : 'GET',
        url  : '../phpfunctions/luckydraw.php?',
        data : {getEligleUserForContest:'true'},
        success: function (data) {
            //console.log(data);
            if(data!='null' ){
                data=JSON.parse(data);
             //   console.log(data);
                var qty=data.length;
                createWheel(data);
            }
            
        },
        error: function(xhr, status, error) {
            console.log(error);
            
        }
    });
}

function updateWinnerList(){
    $.ajax({
        type  : 'GET',
        url  : '../phpfunctions/luckydraw.php?',
        data : {getWinnerList:'true'},
        success: function (data) {
            
            if(data!=null){
                
                data=JSON.parse(data);
                
                $("table.winner_list tbody").empty();
                var dataRow="";
                $.each(data, function(index, obj){
                   
                    dataRow+="<tr><td>"+obj.shortName+" ("+obj.memberId+")</td></tr>";
                });
               
                $("table.winner_list tbody").html(dataRow);
            }
            
        },
        error: function(xhr, status, error) {
            console.log(error);
            
        }
    });
}
</script>

LUCKY DRAW CONTEST REFERAL


Sorry, your browser doesn't support canvas. Please try another.

SPIN
        <img id="prizePointer" src="../js/javascript-winwheel-2.7.0/resources/basic_pointer.png" alt="V" />
    </div>

</div>
<div class="show_toggle" >
<a class="btn hide-on-desktop" id="button-winner-list" style="background:gold;position:fixed;z-index:9999; border:1px solid blue;color:white;user-select: none; ">WINNERS</a>        

<table class="winner_list" >
    <thead>
        <tr>
            <th style="user-select: none; ">
                TODAY's <i class="fa fa-trophy fa-3x" style="color:black" aria-hidden="true"></i>  WINNER
                
            </th>
        </tr>
    </thead>
    <tbody>
      
    </tbody>
</table>
</div>
<?php 
    $eventDate = date('Y-m-d',strtotime('2018-12-28'));
    $todayDate= date("Y-m-d");

    if($todayDate==$eventDate){
        echo '<img src="../resources/Merry-Christmas-Text-PNG-Clipart.png" style="z-index:-100;position:fixed;width:45%;height:50%;right:0px;top:25%;"/>'; 
    }
?>
<script>
        // Create new wheel object specifying the parameters at creation time.

       /* function getRandomColor() {
            var letters = '0123456789ABCDEF';
            var color = '#';
            for (var i = 0; i < 6; i++) {
                color += letters[Math.floor(Math.random() * 16)];
            }
            return color;
        }

*/
function createWheel(data){
dataZ=data;
var qty=data.length;
var participants=[];
$.each(data, function(index, obj){

                participants.push({'fillStyle' : obj.color,'text':obj.memberId});
            });
           
            theWheel = new Winwheel({
            'numSegments'  : qty,     // Specify number of segments.
            'outerRadius'  : 200,   // Set outer radius so wheel fits inside the background.
            'centerX'     : 200,    // correctly position the wheel
            'centerY'     : 200,    // over the background.
            'textFontSize' : 28,    // Set font size as desired.
            'segments'     :        // Define segments including colour and text.

           // [
                participants,
            //   {'fillStyle' : '#eae56f', 'text' : 'Prize 1'},
            //   {'fillStyle' : '#89f26e', 'text' : 'Prize 2'},
            //   {'fillStyle' : '#7de6ef', 'text' : 'Prize 3'},
            //   {'fillStyle' : '#e7706f', 'text' : 'Prize 4'},
            //   {'fillStyle' : '#eae56f', 'text' : 'Prize 5'},
             //  {'fillStyle' : '#89f26e', 'text' : 'Prize 6'},
             //  {'fillStyle' : '#7de6ef', 'text' : 'Prize 7'},
             //  {'fillStyle' : '#7de6ef', 'text' : 'Prize 8'},
             //  {'fillStyle' : '#7de6ef', 'text' : 'Prize 9'},
              // {'fillStyle' : '#e7706f', 'text' : 'Prize 10'}
            //],
            'pins' :  {
        
                'outerRadius' : 5,
                'margin'      : 10,
                'fillStyle'   : 'gold'
            },        
            
            'animation' :           // Specify the animation to use.
            {
                'type'     : 'spinToStop',
                'duration' : 10,     // Duration in seconds.
                'spins'    : 10,     // Number of complete spins.
                'callbackSound' : playSound,    // Specify function to call when sound is to be triggered
                'soundTrigger'  : 'pin', // Pins trigger the sound for this animation.
                'callbackFinished' : alertPrize
                
            }
        });
        }
        var audio = new Audio('../js/javascript-winwheel-2.7.0/resources/tick.mp3');  // Create audio object and load desired file.
        function playSound()
        {
            // Stop and rewind the sound (stops it if already playing).
            audio.pause();
            audio.currentTime = 0;
    
            // Play the sound.
            audio.play();
        }

        // Vars used by the code in this page to do power controls.
        var wheelPower    = 0;
        var wheelSpinning = false;

        // -------------------------------------------------------
        // Function to handle the onClick on the power buttons.
        // -------------------------------------------------------
        function powerSelected(powerLevel)
        {
            // Ensure that power can't be changed while wheel is spinning.
            if (wheelSpinning == false)
            {
                // Reset all to grey incase this is not the first time the user has selected the power.
                document.getElementById('pw1').className = "";
                document.getElementById('pw2').className = "";
                document.getElementById('pw3').className = "";

                // Now light up all cells below-and-including the one selected by changing the class.
                if (powerLevel >= 1)
                {
                    document.getElementById('pw1').className = "pw1";
                }

                if (powerLevel >= 2)
                {
                    document.getElementById('pw2').className = "pw2";
                }

                if (powerLevel >= 3)
                {
                    document.getElementById('pw3').className = "pw3";
                }

                // Set wheelPower var used when spin button is clicked.
                wheelPower = powerLevel;

                // Light up the spin button by changing it's source image and adding a clickable class to it.
                //document.getElementById('spin_button').src = "spin_on.png";
              //  document.getElementById('spin_button').className = "clickable";
            }
        }

        // -------------------------------------------------------
        // Click handler for spin button.
        // -------------------------------------------------------
        function startSpin()
        {
            
    
            // Ensure that spinning can't be clicked again while already running.
            if (wheelSpinning == false)
            {
                // Based on the power level selected adjust the number of spins for the wheel, the more times is has
                // to rotate with the duration of the animation the quicker the wheel spins.
                if (wheelPower == 1)
                {
                    theWheel.animation.spins = 3;
                }
                else if (wheelPower == 2)
                {
                    theWheel.animation.spins = 8;
                }
                else if (wheelPower == 3)
                {
                    theWheel.animation.spins = 15;
                }

                // Disable the spin button so can't click again while wheel is spinning.
               // document.getElementById('spin_button').src       = "spin_off.png";
              //  document.getElementById('spin_button').className = "";

                // Begin the spin animation by calling startAnimation on the wheel object.
                theWheel.startAnimation();
                
                // Set to true so that power can't be changed and spin button re-enabled during
                // the current animation. The user will have to reset before spinning again.
                wheelSpinning = true;
            }
        }

        // -------------------------------------------------------
        // Function for reset button.
        // -------------------------------------------------------
        function resetWheel()
        {
            theWheel.stopAnimation(false);  // Stop the animation, false as param so does not call callback function.
            theWheel.rotationAngle = 0;     // Re-set the wheel angle to 0 degrees.
            theWheel.draw();                // Call draw to render changes to the wheel.

           // document.getElementById('pw1').className = "";  // Remove all colours from the power level indicators.
           // document.getElementById('pw2').className = "";
          //  document.getElementById('pw3').className = "";

            wheelSpinning = false;          // Reset to false to power buttons and spin can be clicked again.
        }

        // -------------------------------------------------------
        // Called when the spin animation has finished by the callback feature of the wheel because I specified callback in the parameters
        // note the indicated segment is passed in as a parmeter as 99% of the time you will want to know this to inform the user of their prize.
        // -------------------------------------------------------
        function alertPrize(indicatedSegment)
        {
            $.each(dataZ, function(index, obj){
                
                if(obj.memberId==indicatedSegment.text){
                    $("#winner_name").text(obj.name);
                    $("#winner_memberId").text(obj.memberId);
                    updateReferalTableWinner(obj.userId);
                    return false; 
                }
               
            });
           
            $("#winnerModal").modal();
            wheelSpinning = false;
            // Do basic alert of the segment text. You would probably want to do something more interesting with this information.
          //  alert("You have won " + indicatedSegment.text);
        }
       
    </script>
                <div class="modal-body" >
                
                    <div style="text-align:center"  >
                        <i class="fa fa-star" aria-hidden="true"></i>
                        <i class="fa fa-star" aria-hidden="true"></i>
                        <i class="fa fa-star" aria-hidden="true"></i>
                        <i class="fa fa-star" aria-hidden="true"></i>
                        <i class="fa fa-star" aria-hidden="true"></i>
                       
                        <br/>
                        
                        <i class="fa fa-trophy fa-5x" style="color:gold" aria-hidden="true"></i> 
                        <br/>
                        <h5 id="winner_memberId" class="display-5"><h5>
                        <hr/>
                            <h3 class="display-3" id="winner_name"></h3>    
                        </table>
                    </div>

                </div>
               
            </div>
        </div>
    </div>
<!--WINNER modal END-->

<!--USER LIST UPDATE REFERAL   modal START-->
<div class="modal fade " id="referalUserListModal" tabindex="-1" role="dialog" aria-labelledby="referalUserListModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-full" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="referalUserListModalLongTitle">UPDATE USERS REFERAL</h5>
                
            </div>
            <div class="modal-body">
                <div class="table-responsive" >
                    <?php
                        echo referalUserListTable();
                    ?>
                </div>
            </div>
            <div class="modal-footer">
                <button  type="button" class="btn btn-secondary btn-block" data-dismiss="modal" >
                    CLOSE
                </button>
            </div>
        </div>
    </div>
</div>
<!--USER LIST UPDATE REFERAL  modal END-->

I make 3 Part of WinWheel but i got every time alert message

<title>HTML5 Canvas Winning Wheel</title> <script type="text/javascript" src="Winwheel.js"></script> <script src="TweenMax.min.js"></script>


Power
High
Med
Low

Spin

ย ย  Play Again
ย ย ย ย ย (reset)

Sorry, your browser doesn't support canvas. Please try another.

<script> // Define the outer wheel, we will treat this as the PRIMARY which means it clears the canvas when drawing and also // gets the animaton applied to it. We must callback a function during the animation to move and draw the inner wheel // so the 2 wheels appear as one thing on the canvas. var outerWheel = new Winwheel({ 'numSegments': 10, 'textMargin' : 0, 'textLineWidth' : 1, 'outerRadius' : 210, 'innerRadius' : 130, // Set inner radius to the size of the inner wheel since the inner part of the wheel 'segments': [ // is being drawn by the inner wheel we don't need to draw there. {'fillStyle' : '#8C8A42', 'text' : '0'}, {'fillStyle' : '#F2F0A8', 'text' : '1'}, {'fillStyle' : '#519142', 'text' : '2'}, {'fillStyle' : '#B7F7A8', 'text' : '3'}, {'fillStyle' : '#4B898F', 'text' : '4'}, {'fillStyle' : '#B1EFF5', 'text' : '5'}, {'fillStyle' : '#8A4342', 'text' : '6'}, {'fillStyle' : '#F0A9A8', 'text' : '7'}, {'fillStyle' : '#B1EFF5', 'text' : '8'}, {'fillStyle' : '#8A4342', 'text' : '9'},
            ],
            'animation':
            {
              'type': 'spinToStop',                     // Define animation more or less as normal, except for the callbackAfter().
              'duration': 6,
              'spins': 15,
            }
        });
        // Need to create the SECONDARY wheel first because on construct the variable which keeps track of the wheel to animate will
        // be set to the last created wheel, and we want the outer one the primary with the animation etc.
        var innerWheel = new Winwheel({
            'numSegments' : 10,
            'outerRadius' : 140,       // Set the outer radius to make the wheel smaller than the outer wheel.
            'innerRadius' : 20,
            'textMargin' : 30,
            'segments': [           //   is being drawn by the inner wheel we don't need to draw there.
                {'fillStyle' : '#8C8A42', 'text' : '0'},
                {'fillStyle' : '#F2F0A8', 'text' : '1'},
                {'fillStyle' : '#519142', 'text' : '2'},
                {'fillStyle' : '#B7F7A8', 'text' : '3'},
                {'fillStyle' : '#4B898F', 'text' : '4'},
                {'fillStyle' : '#B1EFF5', 'text' : '5'},
                {'fillStyle' : '#8A4342', 'text' : '6'},
                {'fillStyle' : '#F0A9A8', 'text' : '7'},
                {'fillStyle' : '#B1EFF5', 'text' : '8'},
                {'fillStyle' : '#8A4342', 'text' : '9'},

            ],
            'animation':
            {
              'type': 'spinToStop',                     // Define animation more or less as normal, except for the callbackAfter().
              'duration': 8,
              'callbackAfter' : drawOuterWheel,
              'callbackBefore' : drawInnerMostAgain,
              'spins': 15,
             
            }
        });

        var innerMostWheel = new Winwheel({
            'numSegments' : 10,
            'outerRadius' : 70,        // Set the outer radius to make the wheel smaller than the outer wheel.
            'segments': [           //   is being drawn by the inner wheel we don't need to draw there.
                {'fillStyle' : '#8C8A42', 'text' : '0'},
                {'fillStyle' : '#F2F0A8', 'text' : '1'},
                {'fillStyle' : '#519142', 'text' : '2'},
                {'fillStyle' : '#B7F7A8', 'text' : '3'},
                {'fillStyle' : '#4B898F', 'text' : '4'},
                {'fillStyle' : '#B1EFF5', 'text' : '5'},
                {'fillStyle' : '#8A4342', 'text' : '6'},
                {'fillStyle' : '#F0A9A8', 'text' : '7'},
                {'fillStyle' : '#B1EFF5', 'text' : '8'},
                {'fillStyle' : '#8A4342', 'text' : '9'},

            ],
            'animation':
            {
              'type': 'spinToStop',                     // Define animation more or less as normal, except for the callbackAfter().
              'duration': 10,
              'callbackAfter' : drawOuterWheel,
              'callbackBefore' : drawInnerAgain,
              'callbackFinished' : alertPrize,
              'spins': 15,
             }
        });

        
        outerWheel.draw();
        innerWheel.draw(false);   
        innerMostWheel.draw(false);
        
       
       /* function CallInnerAnimation(){
              innerWheel.startAnimation();
        }
        function CallInnerMostAnimation(){
              innerMostWheel.startAnimation();
        }*/
        function drawOuterWheel(){
            outerWheel.draw(false); 
        }
       function drawInnerAgain(){
            innerWheel.draw(false);
            
       }
       function drawInnerMostAgain(){
            innerMostWheel.draw(false);
       }
        // Called when the animation has finished.
        function alertPrize()
        {
            // The the indicated segments from the 2 wheels.
            var winningInnerSegment = innerWheel.getIndicatedSegment();
            var winningInnerMostSegment = innerMostWheel.getIndicatedSegment();
            var winningOuterSegment = outerWheel.getIndicatedSegment();
           
            
            alert('You won ' +  ' Outer Segment :  ' +  winningOuterSegment.text  + ', ' + 'Inner Segment : ' + winningInnerSegment.text + ',' + 'Inner Most Segment : ' + winningInnerMostSegment.text);
          
            // Set things so power and spin button can be clicked again.
            wheelSpinning = false;

            // Remove all colours from the power level indicators.
            document.getElementById('pw1').className = "";
            document.getElementById('pw2').className = "";
            document.getElementById('pw3').className = "";
        }


        // ================================================================================================================
        // FUNCTIONS FOR power controls below (All this is not necessary to actually create and spin a wheel)....
        // Vars used by the code in this page to do power controls.
        var wheelPower    = 0;
        var wheelSpinning = false;

        // -------------------------------------------------------
        // Function to handle the onClick on the power buttons.
        // -------------------------------------------------------
        function powerSelected(powerLevel)
        {
            // Ensure that power can't be changed while wheel is spinning.
            if (wheelSpinning == false)
            {
                // Reset all to grey incase this is not the first time the user has selected the power.
                document.getElementById('pw1').className = "";
                document.getElementById('pw2').className = "";
                document.getElementById('pw3').className = "";

                // Now light up all cells below-and-including the one selected by changing the class.
                if (powerLevel >= 1)
                {
                    document.getElementById('pw1').className = "pw1";
                }

                if (powerLevel >= 2)
                {
                    document.getElementById('pw2').className = "pw2";
                }

                if (powerLevel >= 3)
                {
                    document.getElementById('pw3').className = "pw3";
                }

                // Set wheelPower var used when spin button is clicked.
                wheelPower = powerLevel;

                // Light up the spin button by changing it's source image and adding a clickable class to it.
                document.getElementById('spin_button').src = "spin_on.png";
                document.getElementById('spin_button').className = "clickable";
            }
        }
        function resetWheel()
        {
            outerWheel.stopAnimation(false);  // Stop the animation, false as param so does not call callback function.
            outerWheel.rotationAngle = 0;     // Re-set the wheel angle to 0 degrees.
            outerWheel.draw(); 
            
            innerWheel.rotationAngle = outerWheel.rotationAngle;               // Call draw to render changes to the wheel.
            innerWheel.draw(false);
            
            innerMostWheel.rotationAngle = innerWheel.rotationAngle;
            innerMostWheel.draw(false);
            
            document.getElementById('pw1').className = "";  // Remove all colours from the power level indicators.
            document.getElementById('pw2').className = "";
            document.getElementById('pw3').className = "";

            wheelSpinning = false;          // Reset to false to power buttons and spin can be clicked again.
        }

        // -------------------------------------------------------
        // Click handler for spin button.
        // -------------------------------------------------------
        function startSpin()
        {
            if (wheelSpinning == false)
            {
                if (wheelPower == 1)
                {
                    outerWheel.animation.spins = 3;     // Number of spins and/or duration can be altered to make the wheel
                }
                else if (wheelPower == 2)
                {
                    outerWheel.animation.spins = 8;
                }
                else if (wheelPower == 3)
                {
                    outerWheel.animation.spins = 15;
                }

                // Disable the spin button so can't click again while wheel is spinning.
                document.getElementById('spin_button').src = "spin_off.png";
                document.getElementById('spin_button').className = "";

                // Begin the spin animation by calling startAnimation on the wheel object.
                outerWheel.startAnimation(0)
                innerWheel.startAnimation(1);
                innerMostWheel.startAnimation(2);
                // Set to true so that power can't be changed and spin button re-enabled during
                // the current animation. The user will have to reset before spinning again.
                wheelSpinning = true;
            }
        }
    </script>
</body>

Two part wheel with multiple winners

Hi,

I am using two part wheel example. Here my goal is to pick the random winners (Multiple winners) based on were the outer and inner wheel segements stops, not based on the pointer .

So I am making inner wheel rotation angle to minus of outer wheel angle.
innerWheel.rotationAngle = -outerWheel.rotationAngle;

After making above change both inner and outer wheel animates in reverse order. Once the both wheel stops, the position or segments of the inner and outer wheel stops at little random place not in same line.

Can you please suggest How I can stops both wheel segments in same line or aligned. You can see the attached image how the inner wheel segments stops and outer wheel.

Also attached HTML as txt file for reference.
index.txt

Thanks
Shivanagouda
capture2

randomplaceinnerwheel

Animation of more than one wheel does not work

There is an issue with the way the current animation loop is implemented where if there is more than one wheel on the page, starting the animation of the second wheel kills the animation of the first.

Need to allow a way for multiple wheels on the same canvas to be animated, and also preferably all wheels on any canvases on the screen.

Think the issue at the moment is just that there is a single variable on the page called winwheelToDrawDuring animation and this needs to change to an array of wheel objects.

The winwheelAnimationLoop() function then needs to loop though the array of wheels to draw and call the draw method in them along with any animation before and after callbacks for the wheel.

Might also need to change the way the winwheelAnimationLoop() function is added to the GreenSock ticker; have this happen outside any particular wheel. This might mean that the ticker is always running and the wheels always updating even when not animated. This could be a good or a bad thing. Might be able to add parameter to the wheel to keep track of the animation state and only re-draw the wheels when animating.

Also look to have at adding all wheels to the array of wheels to draw automatically at time of creation, rather than when animation start is called - unless use this array to add and remove wheels to be animated - i.e. add on animation start, remove on animation end - that might solve the issue above of not wanting to re-draw static wheels.

If this is all sorted also create a "Multiwheel" example for the examples folder and look to create tutorial for this on the site. Check existing animation tutorials too in case they need to be updated.

Calculate Prize function is not working

@zarocknz first of all, I want to thank you for your work, is really great, the documentation is very good!

I referred "http://dougtesting.net/winwheel/docs/tut14_setting_the_prize" and tried to set the prize before the spin. I want to stop in first segments as always. But it didn't work. Am I missing anything?

// Spin JS Start
// Create new wheel object specifying the parameters at creation time.
var theWheel = new Winwheel({
    'numSegments': 3, // Specify number of segments.
    'outerRadius': 0, // Set outer radius so wheel fits inside the background.
    'drawMode': 'image',
    'segments': [{
            'text': 'Prize 1'
                }, {
            'text': 'Prize 2'
                }, {
            'text': 'Prize 3'
                }
            ],
    'animation': // Specify the animation to use.
    {
        'type': 'spinToStop',
        'duration': 5, // Duration in seconds.
        'spins': 8, // Number of complete spins.
        'callbackFinished': alertPrize,
        'callbackSound': playSound
    }
});
var audio = new Audio('./assets/img/tick.mp3');

function playSound() {
    // Stop and rewind the sound (stops it if already playing).
    audio.pause();
    audio.currentTime = 0;
    // Play the sound.
    audio.play();
}
// Create new image object in memory.
var loadedImg = new Image();
// Create callback to execute once the image has finished loading.
loadedImg.onload = function () {
    theWheel.wheelImage = loadedImg; // Make wheelImage equal the loaded image object.
    theWheel.draw(); // Also call draw function to render the wheel.
}
// Set the image source, once complete this will trigger the onLoad callback (above).
loadedImg.src = "./assets/img/planes.png";
// Vars used by the code in this page to do power controls.
var wheelPower = 0;
var wheelSpinning = false;
// -------------------------------------------------------
// Click handler for spin button.
// -------------------------------------------------------
function startSpin() {
    // Ensure that spinning can't be clicked again while already running.
    if (wheelSpinning == false) {
        theWheel.animation.spins = 5;
        $("#spin-form input").prop('disabled', true);
        // Begin the spin animation by calling startAnimation on the wheel object.
        theWheel.startAnimation();
        // Set to true so that power can't be changed and spin button re-enabled during
        // the current animation. The user will have to reset before spinning again.
        wheelSpinning = true;
    }
}

// Function with the formula to work out stopAngle before spinning animation.
// Called from Click of the Spin button.
function calculatePrize() {
    var stopAt = theWheel.getRandomForSegment(1);
    theWheel.animation.stopAngle = stopAt;
    theWheel.startAnimation();
}


// -------------------------------------------------------
// Called when the spin animation has finished by the callback feature of the wheel because I specified callback in the parameters.
// note the indicated segment is passed in as a parameter as 99% of the time you will want to know this to inform the user of their prize.
// -------------------------------------------------------
function alertPrize(indicatedSegment) {
    // Do basic alert of the segment text. You would probably want to do something more interesting with this information.
    alert("The wheel stopped on " + indicatedSegment.text);
    $('#discode').val(indicatedSegment.text);
}
// Spin JS End

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.