Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add day night curve

  • Loading branch information...
commit 1c0c893610860c4460502601c4a8cd9f61f9d36c 1 parent 8512bed
Richard Zhang authored

Showing 2 changed files with 108 additions and 1 deletion. Show diff stats Hide diff stats

  1. +108 1 worldMap.js
  2. BIN  worldMapDemo.png
109 worldMap.js
... ... @@ -1,3 +1,4 @@
  1 +
1 2 var Map = function() {
2 3 var lands = [];
3 4
@@ -5696,6 +5697,110 @@ var Map = function() {
5696 5697 context.fill();
5697 5698 };
5698 5699
  5700 +
  5701 +
  5702 + this.dayOfYear = function(day) {
  5703 + var dayOne = new Date(day.getFullYear(), 0, 1);
  5704 + return Math.ceil((day.getTime() - dayOne.getTime()) / (24 * 60 * 60 * 1000));
  5705 + };
  5706 +
  5707 + this.hourOfDay = function(day) {
  5708 + return day.getUTCHours() + (day.getUTCMinutes() * 60 + day.getUTCSeconds()) / (60 * 60);
  5709 + };
  5710 +
  5711 + this.nightLength = function(doy, lat) {
  5712 + // Ref: http://mathforum.org/library/drmath/view/56478.html
  5713 +
  5714 + var P1 = .961396 * Math.tan(.00860 * (doy - 186))
  5715 + , P = Math.asin(.39795 * Math.cos(.2163108 + 2 * Math.atan(P1)))
  5716 + , D1 = Math.sin(0.833 * Math.PI / 180) + Math.sin(lat * Math.PI / 180) * Math.sin(P)
  5717 + , D2 = Math.cos(lat * Math.PI / 180) * Math.cos(P)
  5718 + , D = 24 - (24 / Math.PI) * Math.acos(D1 / D2)
  5719 + , N = (24 / Math.PI) * Math.acos(D1 / D2);
  5720 +
  5721 + return Math.acos(D1 / D2) / Math.PI;
  5722 + };
  5723 +
  5724 + this.drawNightLine = function(context, x1, x2, y, w100p) {
  5725 + var maxOpacity = 0.3;
  5726 +
  5727 + if (w100p || x2 - x1 <= 24) {
  5728 + this.line(context, x1, x2, y, 'rgba(0, 0, 0, ' + maxOpacity + ')');
  5729 + } else if (x2 - x1 > 20) {
  5730 + var glen = Math.min(20, Math.floor((x2 - x1) / 10));
  5731 + this.drawGradientLine(context, x1, x2, y, glen, maxOpacity);
  5732 + }
  5733 + };
  5734 +
  5735 + this.drawGradientLine = function(context, x1, x2, y, glen, opacity) {
  5736 + var grad = context.createLinearGradient(x1, y, x1 + glen, y);
  5737 + grad.addColorStop(0, 'rgba(0, 0, 0, 0)');
  5738 + grad.addColorStop(1, 'rgba(0, 0, 0, ' + opacity + ')');
  5739 + this.line(context, x1, x1 + glen, y, grad);
  5740 +
  5741 + this.line(context, x1 + glen, x2 - glen, y, 'rgba(0, 0, 0, ' + opacity + ')');
  5742 +
  5743 + grad = context.createLinearGradient(x2 - glen, y, x2, y);
  5744 + grad.addColorStop(0, 'rgba(0, 0, 0, ' + opacity + ')');
  5745 + grad.addColorStop(1, 'rgba(0, 0, 0, 0)');
  5746 + this.line(context, x2 - glen, x2, y, grad);
  5747 + };
  5748 +
  5749 + this.line = function(context, x1, x2, y, style) {
  5750 + context.strokeStyle = style;
  5751 + context.beginPath();
  5752 + context.moveTo(x1, y);
  5753 + context.lineTo(x2, y);
  5754 + context.closePath();
  5755 + context.stroke();
  5756 + };
  5757 +
  5758 + this.drawDayNight = function(context, mapArea) {
  5759 + var canvas = context.canvas
  5760 + , w = mapArea.width
  5761 + , today = new Date()
  5762 + , doy = this.dayOfYear(today)
  5763 + , hod = this.hourOfDay(today)
  5764 + , offset1 = - Math.floor(hod * w / 24) + mapArea.x
  5765 + , offset2 = w + offset1;
  5766 +
  5767 + context.save();
  5768 + context.beginPath();
  5769 + context.rect(mapArea.x, mapArea.y, mapArea.width, mapArea.height);
  5770 + context.clip();
  5771 +
  5772 + context.globalCompositeOperation = 'darker';
  5773 +
  5774 + this.drawNight(context, doy, offset1, mapArea);
  5775 + this.drawNight(context, doy, offset2, mapArea);
  5776 +
  5777 + context.restore();
  5778 + };
  5779 +
  5780 + this.drawNight = function(context, doy, offset, mapArea) {
  5781 + var canvas = context.canvas
  5782 + , w = mapArea.width
  5783 + , h = mapArea.height
  5784 + , halfW = w / 2
  5785 + , halfH = h / 2;
  5786 +
  5787 + for (var i = 0; i < mapArea.height; i ++) {
  5788 + var lat = 90 - (i * 180 / mapArea.height)
  5789 + , nl = this.nightLength(doy, lat);
  5790 +
  5791 + if (isNaN(nl)) {
  5792 + if ((doy < 79 || doy > 268) && i < halfH) {
  5793 + this.drawNightLine(context, offset, halfW * 2 + offset, i + mapArea.y, true);
  5794 + } else if ((doy > 80 && doy < 267) && i > halfH) {
  5795 + this.drawNightLine(context, offset, halfW * 2 + offset, i + mapArea.y, true);
  5796 + }
  5797 + } else {
  5798 + var half = nl * w / 2;
  5799 + this.drawNightLine(context, (halfW - half) + offset, (halfW + half) + offset, i + mapArea.y);
  5800 + }
  5801 + }
  5802 + };
  5803 +
5699 5804 /**
5700 5805 * options: { mapArea: { x: _, y: _, width: _, height: _ }
5701 5806 * , style: { background: { stroke: 'stroke style', fill: 'fill style' }
@@ -5721,6 +5826,8 @@ var Map = function() {
5721 5826 if (land.length) { this.drawLand(context, land, landStyle, mapArea); }
5722 5827 }
5723 5828
  5829 + this.drawDayNight(context, mapArea);
  5830 +
5724 5831 if (callback) { callback(); }
5725 5832 };
5726   -};
  5833 +};
BIN  worldMapDemo.png

0 comments on commit 1c0c893

Please sign in to comment.
Something went wrong with that request. Please try again.