Giter VIP home page Giter VIP logo

Comments (54)

matthewrice345 avatar matthewrice345 commented on May 13, 2024

This would be a great feature!

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

I'm working on this! :D

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

i'm thinking i could rewrite the me.video.init to have 2 more parameters, autoresize, and autozoom. So you face with four different scenarios:

  • AutoResize: false, AutoZoom: false => What happens now in melonJS, you have always the same canvas size, even if you resize the window.
  • AutoResize: true, AutoZoom: false => The size of the canvas always it the size of the window, but you don't do zoom, so you end up increasing or decreasing the amount of map that is shown on the screen (maybe useful in some RPGs?)
  • AutoResize: false, AutoZoom: true => Does Zoom Keeping the Aspect Ratio of the game
  • AutoResize: true, AutoZoom: true => Does Zoom on the game, but it allows some deformities of the aspect ratio. ?? it need more work...

just tell me what you think...

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

@andyveliz I set this ticket to milestone 0.9.5 as part of my wish list for the next version.

A few suggestions:

AutoZoom should also scale the pixel size by the same ratio that it fills the browser, of course, maintaining the same aspect ratio like you said.

AutoResize = true, AutoZoom = true: The canvas should first be AutoZoomed, like above, and then the canvas resized to fill any empty space in the browser.

Here are some images to help visualize. The white space in the browser is NOT part of the canvas. The black space in the browser IS part of the canvas (rendering the melonJS background color, if any).

AutoResize = false, AutoZoom = false:
Normal

AutoResize = true, AutoZoom = false:
AutoResize

AutoResize = false, AutoZoom = true:
AutoZoom

AutoResize = true, AutoZoom = true:
AutoResize and AutoZoom

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

Great... thanks for the images... that really clarified a lot...

i'll try to submit some code for you to see in the next few weeks...
i hope i can help..

from melonjs.

neilcauldwell avatar neilcauldwell commented on May 13, 2024

Parasyte's images look good and might negate the following suggestion...

It would be great to be able to specify which dimensions are resized.

    1. Scale to the view port size whilst retaining aspect ratio
    1. Resize height of canvas
    1. Resize width of canvas

Example: http://www.freeimagehosting.net/6a8aj

Does anyone have a fork with resizing implemented?

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

This feature should have a max-width option so that you can be sure the game is never resized larger than it was designed to be. Otherwise the graphics will start to look bad on larger screens when the resolution is greater than the graphics were made at.

For example, for my game, when it is viewed on a screen with a width larger than 1024px the game is going to be centered and have a box-shadow and there will be additional content on the page, e.g., about info, comments, footer, etc. Using media queries I will remove that extra content when the browser width is 1024px or below so that the game can truly expand to fit the screen when viewed on tablets and phones.

It would also be nice to have a feature to force the game to appear in either portrait or landscape mode when viewed on tablets or phones. One tower defense game I play, Tower Madness is always in portrait mode, and another one, Fieldrunners, is always in landscape mode. Designing a game to look right in both modes, including maps and menus, would be very difficult on smaller screens.

There are orientation media queries.

You can rotate content with CSS3.

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

Hey thanks for all the good ideas!

currently i'm working on this issue, i have just a few non-working test ... :( but i'll commit some code to my fork of melonjs as soon as i can... i'm only working on resizing on the fly the canvas, with the option to maintain the aspect ratio, basically the images that Jason share with us... i think that this could solve the "resizing when changing orientation" issue... i'll be looking to add the other great features you guys wrote about.

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

Hi guys, i've commited some code to my fork, in the canvas-resize branch, it's a hack making the autoresize and autozoom functions work, check them out... any feedback is appreciated, I hope this can be useful to the main repository.

https://github.com/andyveliz/melonJS

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

@greghouston A max[Height|Width] feature is fine. But there are also some other implications to consider when zooming a canvas to larger or smaller than it was designed for.

When zooming the canvas smaller than its native size, you actually _lose quality_ just as much as when the canvas is enlarged. The quality loss is not as obvious when the image is scaled with interpolation, but it comes at a performance cost. In this case, it is more effective to use two (or more) copies of every image in the game, and choose the closest fit when displaying. This is a technique used in 3D rendering for many years, called MipMapping; when a texture is scaled toward 0.5 times its original size, a smaller version of the texture will be used, increasing performance and visual quality.

Likewise on the other end of the spectrum, when enlarging the canvas, you may not want the image scaled with interpolation enabled, to give the game a distinct "pixelated" look. This can be done with CSS using the image-rendering property on the canvas. That affects the entire canvas, but if you also want it to affect sprites that are scaled or rotated within the canvas, you also need to use context.mozImageSmoothingEnabled = false and context.webkitImageSmoothingEnabled = false when drawing the sprites.

So maybe that's a third boolean to pass, whether you want image smoothing enabled (default) or disabled?

@andyveliz I looked through the commit in your canvas-resize branch. The most important thing it has to offer is the math, which I haven't studied yet. It looks pretty good at first glance. And some of the new methods are also very helpful. The one piece of criticism I have is how your hack reuses variables, and also uses the me.sys namespace unnecessarily.

One idea I want to bring up is the possibility of allowing the canvas to properly reflow with other elements in the HTML document, instead of forcing it to the size of the browser viewport. Imagine the body margins have not been set to 0 (the default is always something larger than 0) then you will stretch the browser viewport by making the canvas the same width/height without taking into account the body margin. Imagine if the canvas also had its own margin... Or if the canvas is inside a div element that sits next to a side-navigation menu. Now we hit all kind of complex situations where the canvas cannot be made the same size as the browser viewport.

The ideal solution, I think, is calculating the size of the canvas's parent element content box, and performing one of three operations when autosize OR autozoom are set, where p is the parent element's content box:

  1. If autosize is true: canvas.width = p.width and canvas.height = p.height
  2. Else if autozoom is true AND p.width >= p.height: canvas.height = p.height
  3. Else if autozoom is true AND p.height > p.width: canvas.width = p.width

Some special care must be taken when p == document.body, because the body may have a height that is smaller than the browser viewport height. Easy thing to do for solving that may be unconditionally setting document.body.style.minHeight = window.innerHeight or similar at the top of the window resize event handler.

I know I haven't covered every edge case, but just adding some more details to take into consideration.

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

@parasyte
You're right!
I haven't tough of that... i'll re write the code to take in cosideration the wrapper variable. The resize or zoom should be contained within the object you choose in your html, not always using the full screen.
I took the math from CommandoJS, I think it's allright.

I was thinking about the "max-width" option that @greghouston suggested, it could be a problem if you have a big widescreen, in some games you don't want the player to have the advantage of seeing more map. How do you guys feel about a max-aspect-ratio variable. You can have both, autozoom and autoresize, as long as you don't go too far in your aspect ratio.

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

I think in the case you don't want to show too much of the map, you just want AutoResize = false?

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

I think it may be better to consider this as an exception, so normal players can have a better gaming experience in all the different screen sizes, but at the same time being prepared for bigger screens and more clever players.

I'll write some code, and try to keep it simple.

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

If both AutoResize and AutoZoom are true the game is going to appear very similar from one screen to another varying only as much as the aspect ratio does, e.g., aspect ratio on iPhone is 1.5:1, the iPad is 1.333:1. My monitor is 1.6:1.

What would be nice though is a maintain aspect ratio option so that it acts like embedded flash does. If you set the width of a flash object to 100%, it will scale to fit the width of the parent container and the height of the flash object will have the correct aspect ratio. This is really important in responsive web designs.

To mimic Flash:
AutoResize: true,
AutoZoom: true,
MaintainAspectRatio: true

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

Please provide some images that show how a game will render with this third boolean. You'll now have 2**3 = 8 different modes of resize, instead of just four.

Keep in mind that AutoResize = true will always change the aspect ratio.

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Here is a perfect example. Resize the result container.

http://jsfiddle.net/greghouston/zS7Bu/

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

I just see a broken image.

Failed to load resource: the server responded with a status of 403 (Forbidden) http://www.gamesuncovered.com/uploads/2009/01/10/fieldrunners1-122933.png

But regardless, it looks like what you want is AutoResize = false, AutoZoom = true

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Find any image on the web and put its URL in there.

MaintainAspectRatio would make it so that AutoResize resized to full width and then the height was generated via the original aspect ratio ... just like when an image in HTML is set to width: 100%, height: auto. In the case of images the aspect ratio is built in. In our case the aspect ratio is defined by the original viewport size.

I guess you could make MaintainAspectRatio always fit in the screen in which case sometimes it would use 100% height and sometimes 100% width or that could be an option.

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Quote:
// But regardless, it looks like what you want is AutoResize = false, AutoZoom = true

Not exactly. An image always resizes to full width. In the AutoResize = false, AutoZoom = true example above it has resized to full height.

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Actually, in the use case I am thinking, AutoResize = false, AutoZoom = true: may actually work so you may be right. I was thinking of how it would display in a column on a webpage. Since those columns don't have heights defined it would have to use the width.

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

http://jsfiddle.net/zS7Bu/1/

This is how AutoResize = false, AutoZoom = true is supposed to work. Notice the image is _always_ the correct aspect ratio, especially when the height of the container would cause the bottom of the image to get chopped off. That "chopping off" means the aspect ratio is changing. And that is not what you want.

from melonjs.

 avatar commented on May 13, 2024

as I was also highthing it here :
https://groups.google.com/forum/?fromgroups=#!topic/melonjs/DNI1BWr0m7M

me.sys.scale will need to be modified, to “become” a vector containing the x and y scale ratio, that can be used later to correctly compute mouse coordinates. As from my understanding, currently a use case with AutoResize = true, AutoZoom = true; (does not maintain aspect ratio) won’t work with mouse event (coordinates will be wrong)

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

I agree 100%. Scaling without maintaining aspect ratio will really do some strange things. The backbuffer (when double buffering is enabled) will also need some special handling for this case.

from melonjs.

 avatar commented on May 13, 2024

If I may a couple of other remarks :

  • Instead of adding a resizeViewport function to me.game, I would rather suggest to add a resize function to the viewport object. (note also that if you resize the viewport, you probably also need to update the deadzone values)
  • I’m personally not a big fan of the two additional parameters added to the init function. What about the possibility to specify “auto” for the existing scale parameter, to at least get rid of the autoresize one ? then I have no idea so far concerning the second one :)
  • Why adding a new updateCanvasSize function instead of updating the existing updateDisplaySize one (I’m not sure someone even used it) ? these two function are somehow redundant, with the previous probably even broken

@andyveliz, by the way, that's a great work you did here, thank you for working on this :)

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

Great ideas! well... the autoresize was indeed tricky, but the mouse coordinates are working as far as I tested, correctly.

I think the auto parameter in scale it's a lot easier, I think I use the resizeViewport function in me.game, because the drawManager parameter it's not public, and i needed to update the fullscreen_rect variable. Any ideas about this?

About the updateCanvasSize I created it because it was just a hack, I was a little afraid of breaking some other functionality, but if I have your blessing to mess with it, it will be a lot more elegant.

@parasyte The backbuffer was really tricky, but with my hack it works :D

from melonjs.

 avatar commented on May 13, 2024

@andyveliz Hi !
So i started integrating your code to progress on this topic, and while starting to make some modification, I had a question.

I can see that you actually resize the viewport, I guess that you made this for a good reason, but I don't understand why ? :)

The feature here being basically to scale (maintaining or nor aspect ratio) automatically the display to fit with the browser window size, why do we need this? In my point of view, the offscreen canvas and the corresponding viewport should never changed, as only the displayed canvas is scaled/resized.

thanks for the feedback !

from melonjs.

 avatar commented on May 13, 2024

@parasyte @andyveliz

At this stage (integration + clean-up), I think we need some beta tester here, any volunteer ? :):):)

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

I was looking at graphs for work and ran into this, another example of zooming with the mousewheel and dragging the viewport with mousedown.
http://sigmajs.org/examples/gexf_example.html

Same functionality in an HTML5 game:
https://chrome.google.com/webstore/detail/fieldrunners/lkpikhjbfbffdblahfidklcohlaeabak?utm_source=chrome-ntp-icon

I just want to make sure this sort of functionality will be possible after autoZoom and autoResize.

Another feature that I mentioned in #113 that would be greatly appreciated is a method to assign map layers and objects to at least two different buffers, and to be able to zoom them independently before they are outputted on top of each other on the canvas. For example, I would assign the map layers, object entities, sprites, and animation sheets to the back buffer and gui and hud objects to the front buffer. Zooming with the mousewheel would only effect the back buffer.

An example of this sort of functionality can be seen here:
https://chrome.google.com/webstore/detail/fieldrunners/lkpikhjbfbffdblahfidklcohlaeabak?utm_source=chrome-ntp-icon

from melonjs.

 avatar commented on May 13, 2024

@parasyte @greghouston @andyveliz

Hi Guys,
I would need some advice here before going further, as at this point we have basic automatic scaling stuff working .

What we have here so far :

  • the me.video.init takes the following parameter function(wrapperid, game_width, game_height, doublebuffering, scale, autoresize)
  • double-buffering is now enabled by default if canvas resizing/scaling is requested
  • if scale is equal to 'auto', the canvas will be scaled based on the canvas parent container width and height
  • if autoresize is equal to false (or not present) the canvas will be scaled maintaining the aspect ratio, else it takes the parent container width & height.
  • viewport is kept unchanged for now (to be re-added later)

So a few questions :

  • I would suggest to rename here the autoresize parameter to maintainAspectRatio, as it makes more sense this way, what do you think ?
  • how should we manage viewport resizing ? the engine is also publishing a message on the me.event.WINDOW_ONRESIZE channel, maybe there a cleaner way to implement it through this, instead of adding again a new parameter to the me.video.init function ?

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Renaming autoresize to maintainAspectRatio makes sense to me.

I wonder if there are enough parameters now that it would make sense to make it something like:

function(wrapperid, game_width, game_height, {
doublebuffering: true,
scale: true,
maintainAspectRatio: true
}

Just a thought.

I don't know if it is already built-in or not, but a nice feature would be adding event listeners for window.resize and orientation change so that the game could resize without requiring a refresh of the page. This could even be yet another option.

This game has great incremental resizing:
http://browserquest.mozilla.org/

If you resize the browser small enough it will request, "Please rotate your device to landscape mode". Since our resize is based on the wrapper element, this would be easy to implement with media queries if melonjs resized when there was a window.resize or orientation change.

I sort of think it might be helpful to have a second scale function called zoom. Zoom would not change the canvas size, but either the entire canvas scale or the scale of a buffer. This way if the player is zoomed into the game at 1.5 scale, and then changes orientation on their iPad, the zoom is applied after the canvas scale. So the canvas might have a scale of 2 and zoom be at 1.5.

me.sys.scale
me.sys.zoom

This way also a zoom of 1.5 would have the same effect at all scales. A zoom of 1 being the default. In my game for instance, the mousewheel will effect zoom with a range clamp of 1 to 1.5. Zooming should not effect the canvas size. It almost worked with the now deprecated me.video.scale, but was rather buggy.

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

You might also consider adding me.sys.orientation that would either return a value of portrait or landscape.

from melonjs.

 avatar commented on May 13, 2024

Hi @greghouston

thank you for the feedback,

Concerning notification, the engine publish a message (using minPubSub) on a specific channel, see here : https://github.com/obiot/melonJS/blob/ticket-4/src/video/video.js#L225

but yes, another one for orientation change, and even fullscreen, would be good too (I might think about a generic channel), as the event type is then available in the passed event object.

Concerning the parameters, I will then renamed the auto-resize parameter to maintainAspectRatio.
Also the scale can take a float value ( to specify a fix scaling value) or the auto value for automatic scaling.

Note finally, that for now, the viewport and "backbuffer" canvas size are unchanged, only the "frontbuffer" display canvas is automatically scaled ( i need to add this back, but I wanted first to clean-up the implementation for the basic scaling)

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

Hey Guys! sorry for not being around for a bit. I was getting married, so i was a little busy... hehehe

@obiot
The reason i have to change the viewport size was to change the fullscreen_rect var in the drawManager, the problem i had, was that after resizing the canvas the tiles weren't always drawn so i did a little trace, and found out that you were using that variable to see what tiles shoud be drawn, and that value didn't change when the canvas is resized.

I've also tried changing the size of the backbuffer but that only led to zooming of the map...

i guess maybe you found a better way to do the resizing :)

and I think you're right about changing the name of the variable, it's more descriptive.

i'll test out this new fixes...

from melonjs.

 avatar commented on May 13, 2024

nooo way, you got married ? me too this weekend !!!!!!
Congratulations man :):):)

from melonjs.

andyveliz avatar andyveliz commented on May 13, 2024

hahaha! congrats to you too!!
what a coincidence!
hahahahah

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

@obiot I haven't had a chance to look at this, sadly. Have been super busy since last week, but things are starting to clear up in my schedule. (Also @andyveliz my best friend's sister got married last Friday, and I was part of their wedding! Congratulations to you!)

I'm ok with renaming the variable to "maintainAspectRatio", since it is a little bit more "obvious". Good to see you also took the time to reverse the logic on it when renamed. ;) I also kind of prefer Greg's suggestion of passing an optional settings object.

I'll get to some code review on this either today or tomorrow sometime. :) I encourage others to help us all with code reviews, too. They are incredibly useful!

from melonjs.

 avatar commented on May 13, 2024

oh so you actually know each other, what a small world !
else for sure please take your time, I was certainly not pushing anything :)

from melonjs.

 avatar commented on May 13, 2024

Guys,

I really would like to merge this into the main branch, as it's starting to be difficult to manage as a separate branch, as the main one includes some bug fixes that are also required here (like with the floating object stuff). And I believe this could be a nice first milestone.

what do you think ?

we can then let this one open, or close and create a new ticket for the missing stuff (basically it's the viewport resize)

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

Let me know what you do. If you close this one I'll make another ticket for zoom and another one for resize on orientation change.

from melonjs.

 avatar commented on May 13, 2024

I will merge it a bit later in the main branch, will close this one and create 2 new tickets.

Please have a look after, If I can ask, to ensure I did not miss anything :)

from melonjs.

aaschmitz avatar aaschmitz commented on May 13, 2024

Hi Olivier

I performed some tests with the Screen Auto Resize (for auto resize the canvas, with "auto" scale) and with the hints below (for resize the game DIV):

http://www.html5rocks.com/en/tutorials/casestudies/gopherwoord-studios-resizing-html5-games/

And has worked like a charm!

Thanks!

from melonjs.

 avatar commented on May 13, 2024

@ciangames thank you for the feedback !

from melonjs.

 avatar commented on May 13, 2024

@greghouston

for the orientation change, what I can do is to create a specific channel you can listen to, like how i did for the resize event or even also trigger the resize event on orientation change (so that you just to listen to the resize), but however I don't really see the benefit of the me.sys.orientation since it's already available then using the window.orientation property.

something like this should work : if Math.abs(window.orientation) === 90 then 'portrait' !

from melonjs.

 avatar commented on May 13, 2024

@greghouston

an even better example using the last commit :

// register to the window resize channel me.event.subscribe(me.event.WINDOW_ONRESIZE, function() { if (Math.abs(window.orientation) === 90) { // portrait : do something } else { // paysage : do something else } });

from melonjs.

 avatar commented on May 13, 2024

bonus question to all :

does anyone has an idea on how to remove/fix this "flickering" effect when the window is resizing (as a reminder, when a canvas is resized; it's content is cleared) ? I tried to defer the function call, but it does not change anything....

from melonjs.

greghouston avatar greghouston commented on May 13, 2024

@obiot

Regarding orientation, that makes sense. No need for a ticket for that one.

That just leaves zoom.

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

@obiot: Repainting on resize event like that will cause some performance decrease while resizing. (I know, it's not very common, but maybe it's noticeable on older hardware.)

If that's a concern, you could instead do a "smart" defer, that waits some short period (like 35ms -- perfect for 30fps) and resets itself if the "smart defer" is run again before the 35ms lapse. Then the user resizes by quickly dragging the window handle; the canvas resize will take effect only after the resize handle slows down.

Function.prototype.timeout = function (time /*, args */) {
    var fn = this, args = Array.prototype.slice.call(arguments, 1);
    if (this.delayId) {
        window.clearTimeout(this.delayId);
    }
    this.delayId = window.setTimeout(function() {
        return fn.apply(fn, args);
    }, time || 0);
    return this.delayId;
};

Use it:

me.video.updateDisplaySize.timeout(35, scale, scale);

from melonjs.

 avatar commented on May 13, 2024

@parasyte : yes, I thought about it as well, but is it really a concern ? I tried it on all my machines yesterday and did not notice any lag or issue, so..... and after all it's just re-sizing, people should not spend time resizing the window continuously ?

let's keep anyway this piece of code here, in case of major complains on the feature.
(what would need to be modified in my code is however to clear the pending deferred function, in case another is deferred meanwhile)

from melonjs.

 avatar commented on May 13, 2024

@parasyte : found this blog entry (http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) while googling our suggestion, this could be actually applied to a lots of things in melonJS (mousemove as a start, as in the bottom of the blog entry example)

from melonjs.

 avatar commented on May 13, 2024

@parasyte : else i think that if I could just store the timer id returned by the defer fuction, and clear it before deferring again the next resize function call, it should be enough (for a window resizing). Keep in mind that deferred function are only executed when the stack is empty, which is once every frame.

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

Well, it's not the clearTimeout that will fix the problem with performance, but the actual time passed to setTimeout. I agree it will prevent multiple defers from executing per frame. But for performance you want the delay to be longer than a single frame.

from melonjs.

 avatar commented on May 13, 2024

I'm ok to spend more time on this, but do you really believe it's that critical ?

from melonjs.

 avatar commented on May 13, 2024

So I did that for now (easy & cheap solution). I will give it more attention tonight once back at home, and will try this with my old mbp and several browsers (to see If there is a perfromance issue we should worry about)

from melonjs.

parasyte avatar parasyte commented on May 13, 2024

@obiot: Nope, not at all critical! Just an observation. ;)

from melonjs.

Related Issues (20)

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.