ol-ext/control/piratecontrol.js
2016-03-30 10:07:30 +02:00

231 lines
7.1 KiB
JavaScript

/* Copyright (c) 2016 Jean-Marc VIGLINO,
released under the CeCILL-B license (French BSD license)
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
*/
/** ol.control.PirateMap adds an old map effect on a canvas renderer.
* It colors the map, adds a parchment texture and compass onto the map.
* @param {Object}
* - hue {ol.Color} color to set hue of the map, default #963
* - saturation {Number} saturation of the hue color, default 0.6
* - opacity {Number} opacity of the overimpose image, default 0.7
*/
ol.control.PirateMap = function(options)
{ options = options || {};
var self = this;
this.asset = {};
this.hue = (options.hue ? ol.color.asString(options.hue) : "#963");
this.saturation = options.saturation || 0.6;
this.opacity = options.opacity || 0.7;
// Get image in css
this.asset.back = new Image();
this.asset.back.onload = function(){ if (self.map_) self.map_.renderSync(); }
var i = $("<img>").addClass("pirate_back").appendTo("body");
this.asset.back.src = i.css("background-image").replace(/^url\(\"(.*)\"\)$/,"$1");
i.remove();
this.asset.compass = new Image();
this.asset.compass.onload = function(){ if (self.map_) self.map_.renderSync(); }
var i = $("<img>").addClass("pirate_compass").appendTo("body");
this.asset.compass.src = i.css("background-image").replace(/^url\(\"(.*)\"\)$/,"$1");
i.remove();
var div = document.createElement('div');
div.className = "ol-pirate ol-unselectable ol-control";
ol.control.Control.call(this,
{ element: div,
target: options.target
});
};
ol.inherits(ol.control.PirateMap, ol.control.Control);
/**
* Remove the control from its current map and attach it to the new map.
* Subclasses may set up event handlers to get notified about changes to
* the map here.
* @param {ol.Map} map Map.
* @api stable
*/
ol.control.PirateMap.prototype.setMap = function (map)
{ ol.control.Control.prototype.setMap.call(this, map);
if (this.map_)
{ this.map_.un('precompose', this.drawMask_, this);
this.map_.un('postcompose', this.drawPirate_, this);
}
if (map)
{ map.on('precompose', this.drawMask_, this);
map.on('postcompose', this.drawPirate_, this);
}
this.map_ = map;
};
(function() {
var crop = [[0.023, 0.957], [0, 0.463], [0.007, 0.42], [0.004, 0.397], [0.029, 0.383], [0.013, 0.383], [0.046, 0.367], [0.011, 0.371], [0.004, 0.349], [0.006, 0.297], [0.012, 0.265], [0.007, 0.246], [0.016, 0.191], [0.031, 0.191], [0.019, 0.171], [0.012, 0.1], [0.046, 0.001], [0.071, 0.012], [0.1, 0], [0.186, 0.01], [0.228, 0.008], [0.239, 0.022], [0.25, 0.009], [0.304, 0.002], [0.311, 0.027], [0.313, 0.007], [0.322, 0.064], [0.311, 0.101], [0.329, 0.055], [0.321, 0.018], [0.334, 0.01], [0.496, 0.009], [0.53, 0.019], [0.553, 0.01], [0.615, 0.014], [0.683, 0.03], [0.697, 0.019], [0.728, 0.027], [0.732, 0.066], [0.735, 0.012], [0.752, 0.006], [0.795, 0.014], [0.85, 0.007], [0.929, 0.013], [1, 0.204], [0.994, 0.324], [0.999, 0.393], [0.988, 0.464], [0.947, 0.46], [0.977, 0.47], [0.978, 0.479], [0.99, 0.489], [0.994, 0.572], [0.992, 0.669], [0.982, 0.673], [0.994, 0.689], [1, 0.716], [0.999, 0.81], [0.987, 0.816], [0.996, 0.83], [0.99, 0.894], [0.944, 1], [0.848, 0.993], [0.841, 0.97], [0.837, 0.993], [0.798, 0.981], [0.697, 0.98], [0.653, 0.986], [0.606, 0.981], [0.598, 0.968], [0.598, 0.941], [0.592, 0.982], [0.558, 0.988], [0.507, 0.983], [0.485, 0.988], [0.418, 0.978], [0.4, 0.969], [0.393, 0.98], [0.338, 0.984], [0.304, 0.977], [0.251, 0.984], [0.238, 0.979], [0.252, 0.915], [0.239, 0.969], [0.233, 0.953], [0.23, 0.984], [0.155, 0.971], [0.147, 0.957], [0.142, 0.974], [0.095, 0.976], [0.066, 0.98], [0.023, 0.957]];
ol.control.PirateMap.prototype.drawMask_ = function (event)
{
var ctx = event.context;
var canvas = ctx.canvas;
var w = canvas.width;
var h = canvas.height;
ctx.save();
/*
ctx.lineWidth = 5;
ctx.strokeStyle = "rgba(0,0,0,0.3)";
ctx.beginPath();
ctx.moveTo(w*crop[0][0]+2, h*crop[0][1]+2);
for (var i=1; i<crop.length; i++)
ctx.lineTo(w*crop[i][0]+2, h*crop[i][1]+2);
ctx.closePath();
ctx.stroke();
*/
ctx.beginPath();
ctx.moveTo(w*crop[0][0], h*crop[0][1]);
for (var i=1; i<crop.length; i++)
ctx.lineTo(w*crop[i][0], h*crop[i][1]);
ctx.clip();
};
/** Draw on the final canvas
* @private
*/
function drawlines(ctx, cx, cy, m)
{
ctx.moveTo (cx+m, cy);
ctx.lineTo(cx-m, cy);
ctx.moveTo (cx, cy+m);
ctx.lineTo(cx, cy-m);
ctx.moveTo (cx+m, cy+m);
ctx.lineTo(cx-m, cy-m);
ctx.moveTo (cx+m, cy-m);
ctx.lineTo(cx-m, cy+m);
ctx.moveTo (cx+m/2, cy-3*m/2);
ctx.lineTo(cx-m/2, cy+3*m/2);
ctx.moveTo (cx+m/2, cy+3*m/2);
ctx.lineTo(cx-m/2, cy-3*m/2);
ctx.moveTo (cx+3*m/2, cy+m/2);
ctx.lineTo(cx-3*m/2, cy-m/2);
ctx.moveTo (cx+3*m/2, cy-m/2);
ctx.lineTo(cx-3*m/2, cy+m/2);
}
function drawCompass(ctx, compass, cx, cy, rot, sc, m)
{ ctx.save();
ctx.translate(cx, cy);
ctx.rotate(rot);
ctx.beginPath();
drawlines(ctx, 0, 0, m*1.5)
ctx.stroke();
if (sc)
{ ctx.globalAlpha = 1;
ctx.drawImage (compass, -compass.width/2*sc, -compass.height/2*sc, compass.width*sc, compass.height*sc);
}
ctx.restore();
}
ol.control.PirateMap.prototype.drawPirate_ = function (event)
{ if (!this.map_) return;
var ctx = event.context;
var canvas = ctx.canvas;
var ratio = event.frameState.pixelRatio;
var view = this.map_.getView();
var img = this.asset.back;
var compass = this.asset.compass;
var m = Math.max(canvas.width, canvas.height);
var res = view.getResolution()/ratio;
var rot = view.getRotation();
// Set back color hue
ctx.save();
//ctx.scale(ratio, ratio);
ctx.globalCompositeOperation = "color";
ctx.fillStyle = this.hue;
ctx.globalAlpha = this.saturation;
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.restore();
// Draw back image
ctx.save();
var ext = event.frameState.extent;
var dx = ext[0]/res;
var dy = ext[1]/res;
dx = dx % img.width ;
dy = img.height - dy % img.height;
if (dx<0) dx += img.width;
if (dy<0) dy += img.height;
ctx.globalCompositeOperation = "multiply";
ctx.globalAlpha = this.opacity;
ctx.rotate(rot);
for (var i=-dx-m; i<m; i+=img.width)
for (var j=-dy-m; j<m; j+=img.height)
{ ctx.drawImage(img, i,j);
}
ctx.restore();
// Draw compass
ctx.save();
ctx.lineWidth = 1;
ctx.strokeStyle = this.hue;
ctx.globalCompositeOperation = "multiply";
ctx.globalAlpha = this.opacity;
drawCompass (ctx, compass, canvas.width*0.9, canvas.height*0.9, rot, ratio, m*1.5);
drawCompass (ctx, compass, compass.width/2 + canvas.width*0.05, canvas.height*0.5, rot, 0.5*ratio, m*1.5);
ctx.restore();
// Restore clip
ctx.restore();
/** /
ctx.save();
ctx.strokeStyle = "rgba(0,0,0,0.3)";
ctx.globalCompositeOperation = "multiply";
ctx.globalAlpha = 0.3;
var w=canvas.width;
var h=canvas.height;
for (var lw=3; lw>0; lw--)
{
ctx.beginPath();
ctx.lineWidth = 4*lw;
ctx.moveTo(w*crop[0][0]+2, h*crop[0][1]+2);
for (var i=1; i<crop.length; i++)
ctx.lineTo(w*crop[i][0]+2, h*crop[i][1]+2);
ctx.closePath();
ctx.stroke();
}
ctx.restore();
/**/
}
})();