master
fred 2023-02-25 02:49:24 +01:00
parent ad331f7e5f
commit 45e7624417
27 changed files with 2222 additions and 110 deletions

View File

@ -53,14 +53,14 @@ MYPLAYERKEY=$(grep ${QRCODE} ~/.zen/game/players/*/secret.dunikey | cut -d ':' -
[[ ! $MYPLAYERKEY ]] && MYPLAYERKEY="$HOME/.zen/game/players/.current/secret.dunikey"
## CCHANGE +
$MY_PATH/../tools/jaklis/jaklis.py -k $MYPLAYERKEY send -d "${QRCODE}" -t "CONTACT" -m "Rendez vous
$MY_PATH/../tools/jaklis/jaklis.py-n $myGCHANGE -k $MYPLAYERKEY send -d "${QRCODE}" -t "CONTACT" -m "Rendez vous
sur https://astroport.copylaradio.com/
Saisissez votre URL Youtube Favorite et un email
Activez votre Capsule IPFS
/ipns/$ASTRONAUTENS"
## CESIUM +
$MY_PATH/../tools/jaklis/jaklis.py -n https://g1.data.e-is.pro -k $MYPLAYERKEY send -d "${QRCODE}" -t "CONTACT" -m "Rendez vous
$MY_PATH/../tools/jaklis/jaklis.py -n $myCESIUM -k $MYPLAYERKEY send -d "${QRCODE}" -t "CONTACT" -m "Rendez vous
sur https://astroport.copylaradio.com/
Saisissez votre URL Youtube Favorite et un email
Activez votre Capsule IPFS

View File

@ -7,8 +7,8 @@
# astroport.cancer.copylaradio.com
/ip4/185.202.238.69/tcp/4001/p2p/12D3KooWDYpPdfCFf3CbKpcLNmyA2vmJs4JY55k8yje9R1MxSgdB
# astroport.aries.copylaradio.com
/ip4/37.187.127.175/tcp/4001/p2p/12D3KooWSQYTxeoZZ39SNosEKxi7RUdGTtAQAqpKeZJxjzqqrZTx
# cloud.copylaradio.com
/dnsaddr/cloud.copylaradio.com/p2p/12D3KooWSQYTxeoZZ39SNosEKxi7RUdGTtAQAqpKeZJxjzqqrZTx
# astroport.sonic.copylaradio.com
/ip4/161.97.174.60/tcp/4001/p2p/12D3KooWJki74EkJ8YUhrAfr2UwtQiJKBY94PYLmVnEQe9jo3aqC

BIN
images/g1ticket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -164,102 +164,15 @@ if [[ "$USER" == "pi" ]]; then ## PROPOSE QR_CODE PRINTER SUR RPI
fi
echo "#############################################"
echo "######### PATIENCE #########################"
echo "######### SETUP #########################"
echo "#############################################"
## Scripts pour systemd ou InitV (xbian)
echo "=== SETUP IPFS SYSTEM"
~/.zen/Astroport.ONE/tools/ipfs_setup.sh
echo "/ip4/127.0.0.1/tcp/5001" > ~/.ipfs/api
#### SETUP JAKLIS ###############################################################
echo "=== SETUP jaklis"
cd ~/.zen/Astroport.ONE/tools/jaklis
sudo ./setup.sh
## XBIAN fail2ban ERROR correction ##
#[....] Starting authentication failure monitor: fail2ban No file(s) found for glob /var/log/auth.log
[[ "$USER" == "xbian" ]] && sudo sed -i "s/auth.log/faillog/g" /etc/fail2ban/paths-common.conf
### MODIFIYING /etc/sudoers ###
[[ "$USER" == "xbian" ]] && echo "xbian ALL=(ALL) NOPASSWD:ALL" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/astroport')
# PERSONNAL DEFCON LEVEL
# cp ~/.zen/Astroport.ONE/DEFCON ~/.zen/
if [[ "$USER" == "xbian" ]]
then
echo "enabling ipfs initV service autostart"
cd /etc/rc2.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc3.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc4.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc5.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc0.d && sudo ln -s ../init.d/ipfs K01ipfs
cd /etc/rc1.d && sudo ln -s ../init.d/ipfs K01ipfs
cd /etc/rc6.d && sudo ln -s ../init.d/ipfs K01ipfs
# Disable xbian-config auto launch
echo 0 > ~/.xbian-config-start
fi
########################################################################
# CREATE ~/astroport FILESYSTEM GATE
mkdir -p ~/Astroport/film
mkdir -p ~/Astroport/serie
mkdir -p ~/Astroport/anime
mkdir -p ~/Astroport/page
mkdir -p ~/Astroport/web
mkdir -p ~/Astroport/video
echo '${TYPE};${MEDIAID};${YEAR};${TITLE};${SAISON};${GENRES};_IPNSKEY_;${RES};/ipfs/_IPFSREPFILEID_/$URLENCODE_FILE_NAME' > ~/Astroport/ajouter_video.modele.txt
#######################################################################
echo "#############################################"
## https://darktrojan.github.io/openwith/webextension.html"
~/.zen/Astroport.ONE/open_with_linux.py install
echo "#############################################
# NOURRISSEZ VOTRE BLOB depuis Firefox !!
# https://addons.mozilla.org/firefox/addon/open-with
#############################################
## $HOME/.zen/Astroport.ONE/ajouter_media.sh ##
#############################################"
### ADD 20h12.sh CRON ###############
~/.zen/Astroport.ONE/tools/cron_VRFY.sh ON
########################################################################
# SUDO permissions
########################################################################
## USED FOR fail2ban-client (DEFCON)
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/fail2ban-client" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/fail2ban-client')
## USED FOR RAMDISK (video live streaming)
echo "$USER ALL=(ALL) NOPASSWD:/bin/mount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/mount')
echo "$USER ALL=(ALL) NOPASSWD:/bin/umount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/umount')
## USED FOR SYSTEM UPGRADE
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt-get" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt-get')
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt')
## USED FOR "systemctl restart ipfs"
echo "$USER ALL=(ALL) NOPASSWD:/bin/systemctl" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/systemctl')
## USED FOR "sudo youtube-dl -U"
echo "$USER ALL=(ALL) NOPASSWD:/usr/local/bin/youtube-dl" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/youtube-dl')
echo "#############################################"
echo "# ADDING <<<Astroport>>> DESKTOP SHORTCUT"
[[ -d ~/Bureau ]] && sed "s/_USER_/$USER/g" ~/.zen/Astroport.ONE/astroport.desktop > ~/Bureau/astroport.desktop && chmod +x ~/Bureau/astroport.desktop
[[ -d ~/Desktop ]] && sed "s/_USER_/$USER/g" ~/.zen/Astroport.ONE/astroport.desktop > ~/Desktop/astroport.desktop && chmod +x ~/Desktop/astroport.desktop
mkdir -p ~/.zen/tmp
echo "#############################################"
## INSTALL yt-dlp & SYMLINK youtube-dl
~/.zen/Astroport.ONE/youtube-dl.sh
~/.zen/Astroport.ONE/setup.sh
echo "#############################################"

16
search2
View File

@ -1,16 +0,0 @@
#!/bin/bash
clear
echo "------------------------------------------------------------------------------"
if [ "$1" == "" ]; then
echo " Nothing to search for!"
else
echo " Searching for "$1" recursively. Please Wait..."
echo "------------------------------------------------------------------------------"
grep -h -r --exclude=B00 -H --colour=always "$1" ./
fi
echo "------------------------------------------------------------------------------"
if [ "$2" != "" ]; then
echo " To replace \"$1\" whith \"$2\", please run"
echo " grep -rl '$1' ./ | while read file; do sed -i 's~$1~$2~g' \$file; done"
fi
## THIS IS A GREAT RETRO ENGINEERING AND CODING TOOLS

101
setup.sh Executable file
View File

@ -0,0 +1,101 @@
#!/bin/bash
################################################################################
# Author: Fred (support@qo-op.com)
# Version: 0.1
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
################################################################################
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
ME="${0##*/}"
echo "#############################################"
echo ">>>>>>>>>>> SYSTEM SETUP "
echo "#############################################"
#### SETUP JAKLIS ###############################################################
echo "=== SETUP jaklis"
cd ~/.zen/Astroport.ONE/tools/jaklis
sudo ./setup.sh
## XBIAN fail2ban ERROR correction ##
#[....] Starting authentication failure monitor: fail2ban No file(s) found for glob /var/log/auth.log
[[ "$USER" == "xbian" ]] && sudo sed -i "s/auth.log/faillog/g" /etc/fail2ban/paths-common.conf
### MODIFIYING /etc/sudoers ###
[[ "$USER" == "xbian" ]] && echo "xbian ALL=(ALL) NOPASSWD:ALL" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/astroport')
# PERSONNAL DEFCON LEVEL
# cp ~/.zen/Astroport.ONE/DEFCON ~/.zen/
if [[ "$USER" == "xbian" ]]
then
echo "enabling ipfs initV service autostart"
cd /etc/rc2.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc3.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc4.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc5.d && sudo ln -s ../init.d/ipfs S02ipfs
cd /etc/rc0.d && sudo ln -s ../init.d/ipfs K01ipfs
cd /etc/rc1.d && sudo ln -s ../init.d/ipfs K01ipfs
cd /etc/rc6.d && sudo ln -s ../init.d/ipfs K01ipfs
# Disable xbian-config auto launch
echo 0 > ~/.xbian-config-start
fi
########################################################################
# CREATE ~/astroport FILESYSTEM GATE
mkdir -p ~/Astroport/film
mkdir -p ~/Astroport/serie
mkdir -p ~/Astroport/anime
mkdir -p ~/Astroport/page
mkdir -p ~/Astroport/web
mkdir -p ~/Astroport/video
echo '${TYPE};${MEDIAID};${YEAR};${TITLE};${SAISON};${GENRES};_IPNSKEY_;${RES};/ipfs/_IPFSREPFILEID_/$URLENCODE_FILE_NAME' > ~/Astroport/ajouter_video.modele.txt
#######################################################################
echo "#############################################"
## https://darktrojan.github.io/openwith/webextension.html"
~/.zen/Astroport.ONE/open_with_linux.py install
echo "#############################################
# NOURRISSEZ VOTRE BLOB depuis Firefox !!
# https://addons.mozilla.org/firefox/addon/open-with
#############################################
## $HOME/.zen/Astroport.ONE/ajouter_media.sh ##
#############################################"
### ADD 20h12.sh CRON ###############
~/.zen/Astroport.ONE/tools/cron_VRFY.sh ON
########################################################################
# SUDO permissions
########################################################################
## USED FOR fail2ban-client (DEFCON)
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/fail2ban-client" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/fail2ban-client')
## USED FOR RAMDISK (video live streaming)
echo "$USER ALL=(ALL) NOPASSWD:/bin/mount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/mount')
echo "$USER ALL=(ALL) NOPASSWD:/bin/umount" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/umount')
## USED FOR SYSTEM UPGRADE
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt-get" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt-get')
echo "$USER ALL=(ALL) NOPASSWD:/usr/bin/apt" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/apt')
## USED FOR "systemctl restart ipfs"
echo "$USER ALL=(ALL) NOPASSWD:/bin/systemctl" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/systemctl')
## USED FOR "sudo youtube-dl -U"
echo "$USER ALL=(ALL) NOPASSWD:/usr/local/bin/youtube-dl" | (sudo su -c 'EDITOR="tee" visudo -f /etc/sudoers.d/youtube-dl')
echo "#############################################"
echo "# ADDING <<<Astroport>>> DESKTOP SHORTCUT"
[[ -d ~/Bureau ]] && sed "s/_USER_/$USER/g" ~/.zen/Astroport.ONE/astroport.desktop > ~/Bureau/astroport.desktop && chmod +x ~/Bureau/astroport.desktop
[[ -d ~/Desktop ]] && sed "s/_USER_/$USER/g" ~/.zen/Astroport.ONE/astroport.desktop > ~/Desktop/astroport.desktop && chmod +x ~/Desktop/astroport.desktop
mkdir -p ~/.zen/tmp
echo "#############################################"
## INSTALL yt-dlp & SYMLINK youtube-dl
~/.zen/Astroport.ONE/youtube-dl.sh

View File

@ -388,7 +388,7 @@ myGCHANGE="https://www.gchange.fr"
myCESIUM="https://g1.data.e-is.pro"
myHOST="$(myHostName)"
myIP="$(myIp)"
myIPFS="http://$(myHName):8080"
myIPFS="http://$(myHName).local:8080"
myIPFSGW="$(myIpfsGw)"
myTUBE="$(myTube)"
myASTROTUBE="https://$(myAstroTube)"

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

View File

@ -0,0 +1,99 @@
<!DOCTYPE html>
<html>
<head>
<title>ASTROPORT PORTAL : http://astroport.localhost:1234</title>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="index_fichiers/demo.css">
<link rel="stylesheet" href="index_fichiers/jquery-ui.min.css">
<script type="text/javascript" src="index_fichiers/requestanimationframe.polyfill.js"></script>
<script type="text/javascript" src="index_fichiers/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="index_fichiers/instascan.min.js"></script>
<script type="text/javascript" src="index_fichiers/jquery-ui.0.min.js"></script>
<script type="text/javascript" src="index_fichiers/sphere-hacked.js"></script>
<script type="text/javascript" src="index_fichiers/jquery.earth-3d.js"></script>
<script type="text/javascript" src="index_fichiers/demo.js"></script>
</head>
<body>
<a target=_blank href="https://astroport.copylaradio.com"><img style="position: absolute; top: 0; right: 0; border: 0;" src="l0g0.png" alt="Entrez par le Le Claude"></a>
<h1><a target=_blank href="http://astroport.localhost:1234">Astroport Ŋ1</a></h1>
<div class="subtitle">Une Planète à Vous<br>Un Internet à Nous</div>
<div id="demo">
<div id="description">
<h2>Utilisez <a href="https://cesium.app">Cesium</a> !</h2>
<p><img src="/ipfs/QmWUpjGFuF7NhpXgkrCmx8Tbu4xjcFpKhE7Bsvt6HeKYxu/g1ticket_qrcode.png"></p>
<h3>Ajoutez en commentaire l'email de vos amis...</h3>
<p>NB: "fred@g1sms.fr" a ouvert son compte à <a href="https://opencollective.com/monnaie-libre/projects/stiits">LaSTI</a> il bénéficie du service "G1PalPé"</p>
<br>
<p><a href="https://opencollective.com/monnaie-libre/projects/coeurbox">La♥BOX</a>, téléporte vos DATA 👍 à l'abris dans "Le Claude"</p>
<p>Powered by <a href="https://astroport.com">Astroport</a></p>
<h2>Scannez votre QRCode</h2>
<video id="preview" style="transform: scaleX(-1);width: 220px;height: 220px;"></video>
<script type="text/javascript">
let scanner = new Instascan.Scanner({ video: document.getElementById('preview') });
scanner.addListener('scan', function (content) {
alert("qrcode="+content);
$.ajax({
url: "http://astroport.localhost:1234",
data: "qrcode="+content,
type: 'GET'
});
//
// $(location).attr('href', content);
// Receiver : echo -e 'HTTP/1.1 200 OK\r\n' | nc -l -p 1234 -q 1 | grep '^GET' | cut -d' ' -f2 | cut -d'=' -f 2
});
Instascan.Camera.getCameras().then(function (cameras) {
if (cameras.length > 0) {
scanner.start(cameras[0]);
} else {
console.error('No cameras found.');
}
}).catch(function (e) {
console.error(e);
});
</script>
</div>
<div id="showoff">
<div id="container">
<h2>Envoyez la Ḡ1 au Monde</h2>
<canvas id="sphere" width="400" height="400"></canvas>
<div id="glow-shadows" class="earth"></div>
<canvas id="flights" width="400" height="400"></canvas>
<div id="locations"></div>
</div>
<div class="choose_example">
Choose example: <select id="example">
<option value="simple">Simple earth</option>
<option value="simple_tilted">Simple tilted earth</option>
<option value="simple_mars">Simple mars</option>
<option value="locations">Earth with locations</option>
<option value="flights" selected>Earth with locations and flights</option>
</select>
</div>
<div class="code">
<a href="#" onclick="$('#example_code').show(); $(this).hide().siblings('a').show(); return false;">Show code</a>
<a href="#" style="display: none;" onclick="$('#example_code').hide(); $(this).hide().siblings('a').show(); return false;">Hide code</a>
<textarea id="example_code" onclick="this.focus();this.select();"></textarea>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,149 @@
body {
background: black;
margin: 0;
padding: 0;
color: #DDD;
text-align: center;
padding-bottom: 20px;
}
h1 {
margin-top: 10px;
font-size: 40px;
margin-bottom: 10px;
}
.subtitle {
font-size: 20px;
margin-bottom: 20px;
color: #777;
}
a {
color: white;
}
#demo {
overflow: hidden;
}
#description {
text-align: left;
float: left;
width: 49%;
max-width: 500px;
padding-top: 50px;
padding-left: 20px;
}
#showoff {
float: left;
width: 49%;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#container {
position: relative;
display: inline-block;
width: 400px;
height: 400px;
}
#sphere, #flights, #glow-shadows, #locations, #drag {
position: absolute;
top: 0px;
left: 0px;
width: 400px;
height: 400px;
}
#glow-shadows {
top: 1px;
left: 1px;
}
#glow-shadows.earth {
background: url(../images/earth-glow-shadows.png);
}
#glow-shadows.mars {
background: url(../images/mars-glow-shadows.png);
}
.location {
position: absolute;
width: 10px;
height: 10px;
left: 10px;
top: 10px;
border: 2px solid white;
margin-left: -5px;
margin-top: -5px;
border-radius: 50%;
cursor: pointer;
}
.location:hover {
width: 15px;
height: 15px;
margin-left: -7.5px;
margin-top: -7.5px;
}
.flight {
position: absolute;
width: 24px;
height: 25px;
left: 10px;
top: 10px;
background: url(../images/plain.png);
background-size: 100% 100%;
margin-left: -12px;
margin-top: -12.5px;
cursor: pointer;
}
.flight:hover {
width: 36px;
height: 37.5px;
margin-left: -18px;
margin-top: -18.75px;
}
.choose_example {
width: 35%;
margin-left: 32.5%;
}
#example_code {
width: 100%;
height: 200px;
background-color: black;
color: white;
border: 0px;
resize: none;
display: none;
}
.code {
margin-top: 10px;
}
.social {
display: inline-block;
}
.social.twitter {
vertical-align: -3px;
}
.social.google {
vertical-align: -7px;
}

View File

@ -0,0 +1,208 @@
var examples = {};
examples['simple'] = function() {
$('#sphere').earth3d({
dragElement: $('#locations') // where do we catch the mouse drag
});
};
examples['simple_tilted'] = function() {
$('#sphere').earth3d({
dragElement: $('#locations'), // where do we catch the mouse drag
sphere: { // rotation and size of the planet
tilt: 40,
turn: 20,
r: 10
}
});
};
examples['simple_mars'] = function() {
$('#sphere').earth3d({
texture: 'images/mars1024x1024.jpg', // texture used by planet
dragElement: $('#locations') // where do we catch the mouse drag
});
};
examples['locations'] = function() {
/* defining locations to display.
Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
Any additional key can be reached via callbacks functions.
*/
var locations = {
obj1: {
alpha: Math.PI / 4,
delta: 0,
name: 'location 1'
},
obj2: {
alpha: 1 * Math.PI / 4,
delta: -2 * Math.PI / 4,
name: 'location 2'
},
obj3: {
alpha: 2 * Math.PI / 4,
delta: 0,
name: 'location 3'
},
obj4: {
alpha: 3 * Math.PI / 4,
delta: 3 * Math.PI / 4,
name: 'location 4'
},
obj5: {
alpha: 2.2 * Math.PI / 4,
delta: -1.1 * Math.PI / 4,
name: 'location 5'
}
};
$('#sphere').earth3d({
locationsElement: $('#locations'),
dragElement: $('#locations'), // where do we catch the mouse drag
locations: locations
});
};
examples['flights'] = function() {
/* defining locations to display.
Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
Any additional key can be reached via callbacks functions.
*/
var locations = {
obj1: {
alpha: Math.PI / 4,
delta: 0,
name: 'location 1'
},
obj2: {
alpha: 1 * Math.PI / 4,
delta: -2 * Math.PI / 4,
name: 'location 2'
},
obj3: {
alpha: 2 * Math.PI / 4,
delta: 0,
name: 'location 3'
},
obj4: {
alpha: 3 * Math.PI / 4,
delta: 3 * Math.PI / 4,
name: 'location 4'
},
obj5: {
alpha: 2.2 * Math.PI / 4,
delta: -1.1 * Math.PI / 4,
name: 'location 5'
}
};
/* defining paths to display.
Each path must have a key, an origin and a destination. The values are the location's key.
You can, if you want to, define flights on these paths.
Each flight has a key, a destination (the location's key) and a position.
The position is the progress a fleet has made on its path.
Any additional key can be reach via callbacks functions.
*/
var paths = {
path: {
origin: 'obj1',
destination: 'obj2',
flights: {
flight: {
position: 0.25,
destination: 'obj2',
name: 'Flight 1'
},
flight2: {
position: 0.25,
destination: 'obj1',
name: 'Flight 2'
}
}
},
path2: {
origin: 'obj1',
destination: 'obj3',
flights: {
flight3: {
position: 0.5,
destination: 'obj3',
name: 'Flight 3'
}
}
},
path3: {
origin: 'obj1',
destination: 'obj4',
flights: {
flight4: {
position: 0.5,
destination: 'obj4',
name: 'Flight 4'
}
}
},
path4: {
origin: 'obj1',
destination: 'obj5'
},
path7: {
origin: 'obj1',
destination: 'obj5',
flights: {
flight5: {
position: 0.25,
destination: 'obj7',
name: 'Flight 5'
}
}
}
}
$('#sphere').earth3d({
flightsCanvas: $('#flights'),
locationsElement: $('#locations'),
dragElement: $('#locations'), // where do we catch the mouse drag
paths: paths,
locations: locations
});
};
function selectExample(example) {
$('#sphere').earth3d('destroy');
$('#sphere').replaceWith($('<canvas id="sphere" width="400" height="400"></canvas>'));
$('.location').remove();
$('.flight').remove();
$('#flights')[0].getContext('2d').clearRect(0, 0, 400, 400);
if (example == 'simple_mars') {
$('#glow-shadows').removeClass('earth').addClass('mars');
} else {
$('#glow-shadows').removeClass('mars').addClass('earth');
}
var code = examples[example].toString();
code = code.substring(14);
code = code.substring(0, code.length - 2);
var lines = code.split("\n");
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].substring(2);
}
code = lines.join("\n");
$('#example_code').val(code);
examples[example]();
}
$(document).ready(function() {
selectExample('flights');
$('#example').change(function() {
selectExample($(this).val());
});
});
function addPath() {
$('#sphere').earth3d('changePaths', {path2: {
origin: 'obj1',
destination: 'obj3'
}});
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,849 @@
/*
jquery.earth3d.js
jQuery ui plugin that allow you to draw a beautiful 3d spinning earth on canvas
Author: Sebastien Drouyer
Based on the amazing sphere.js plug of Sam Hasler
Licensed under the MIT license (MIT-LICENSE.txt)
http://sdrdis.github.com/jquery.earth-3d/
Depends:
ui.core.js
Options:
* texture: texture map used by the planet
* sphere: rotation and size of the planet
* defaultSpeed: default spinning speed of the planet
* backToDefaultTime: time (in ms) to return by to default speed when planet is dragged
* locations: locations to display on the planet:
* Each position must have a key, an alpha and delta position (or x and y if you want to display a static location).
Any additional key can be reached via callbacks functions
Example:
{
obj1: {
alpha: Math.PI / 4,
delta: 0,
name: 'location 1'
}
}
* paths: paths and flights to display over the planet:
Each path must have a key, an origin and a destination. The values are the location's key.
You can, if you want to, define flights on these paths.
Each flight has a key, a destination (the location's key) and a position.
The position is the progress a fleet has made on its path.
Any additional key can be reach via callbacks functions.
Example:
{
path: {
origin: 'obj1',
destination: 'obj2',
flights: {
flight: {
position: 0.25,
destination: 'obj2',
name: 'Flight 1'
},
flight2: {
position: 0.25,
destination: 'obj1',
name: 'Flight 2'
}
}
}
}
* flightsCanvas: Dom element which is a canvas and where the flights and paths are drawn
* dragElement: Dom element where we catch the mouse drag
* locationsElement: Dom elements where the locations are drawn
* flightsCanvasPosition: position of the flight canvas (can be use if you have some gap between your planet and your flights
* pixelRadiusMultiplier: (TEMPORARY) used by the getSphereRadiusInPixel (see the functions)
* onInitLocation: callback function which allows you to define what to do when the locations are initialized
* Parameters:
* location: location (coming from locations option)
* widget: earth3d widget object
* onShowLocation: callback function which allows you to define what to do when a location becomes visible (was behind the planet and is now in front of it)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onRefreshLocation: callback function which allows you to define what to do when a location is refreshed (it moves)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onHideLocation: callback function which allows you to define what to do when a location becomes invisible (was in front of the planet and is now behind it)
* Parameters:
* location: location (coming from locations option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onInitFlight: callback function which allows you to define what to do when the flights are initialized
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
* onShowFlight: callback function which allows you to define what to do when a flight becomes visible (was behind the planet and is now in front of it)
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
* onRefreshFlight: callback function which allows you to define what to do when a flight is refreshed (it moves)
* Parameters:
* flight: flight (coming from flights option)
* x: 2d left position
* y: 2d top position
* widget: earth3d widget object
* onHideFlight: callback function which allows you to define what to do when a flight becomes invisible (was in front of the planet and is now behind it)
* Parameters:
* flight: flight (coming from flights option)
* widget: earth3d widget object
Functions
* getSphereRadiusInPixel: function which allows you to get the sphere radius in pixel
/!| WARNING: this function needs to be refactored, since I didn't find out (my maths courses are far away) how to
get the exact value. I did a basic linear regression, but it is not exact, and you will have to change the pixelRadiusMultiplier
option to get the correct value
* destroy: use this function when you want to destroy the object. It will throw a cancel animation frame, so the
CPU won't be used anymore.
* changePaths: use this function when you want to update paths and flights (options on widget)
it will add the callback functions support
*/
var earth3d;
(function($) {
$.widget('ui.earth3d', {
options: {
texture: 'images/earth1024x1024.jpg',
sphere: {
tilt: 0,
turn: 0,
r: 10
},
defaultSpeed: 20,
backToDefaultTime: 4000,
locations: {
},
paths: {
},
flightsCanvas: null,
dragElement: null,
locationsElement: null,
flightsCanvasPosition: {
x: 0,
y: 0
},
tiling: {horizontal: 1, vertical: 1},
pixelRadiusMultiplier: 0.97,
onInitLocation: function(location, widget) {
var $elem = $('<div class="location"></div>');
$elem.appendTo(widget.options.locationsElement);
$elem.click(function() {
alert('Clicked on ' + location.name);
});
location.$element = $elem;
},
onShowLocation: function(location, x, y) {
location.$element.show();
},
onRefreshLocation: function(location, x, y) {
//console.log(x, y);
location.$element.css({
left: x,
top: y
});
},
onHideLocation: function(location, x, y) {
location.$element.hide();
},
onDeleteLocation: function(location) {
location.$element.remove();
},
onInitFlight: function(flight, widget) {
var $elem = $('<div class="flight"></div>');
$elem.appendTo(widget.options.locationsElement);
$elem.click(function() {
alert('Clicked on ' + flight.name);
});
flight.$element = $elem;
},
onShowFlight: function(flight) {
flight.$element.show();
},
onRefreshFlight: function(flight, x, y, angle, widget) {
flight.$element.css({
left: x,
top: y,
'-webkit-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)',
'-moz-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)',
'-o-transform':'rotate(' + ((angle + Math.PI / 2) * 360 / (2 * Math.PI)) + 'deg)'
});
},
onHideFlight: function(flight) {
flight.$element.hide();
},
onDeleteFlight: function(flight) {
flight.$element.remove();
}
},
earth: null,
posVar: 24 * 3600 * 1000,
lastMousePos: null,
lastSpeed: null,
lastTime: null,
lastTurnByTime: null,
textureWidth: null,
textureHeight: null,
obj: null,
flightsCtx: null,
renderAnimationFrameId: null,
mousePressed: null,
_create: function() {
earth3d = this;
var self = this;
this.obj = $('div');
if (this.options.flightsCanvas !== null) {
this.flightsCtx = this.options.flightsCanvas[0].getContext('2d');
}
createSphere(this.element[0], this.options.texture, function(earth, textureWidth, textureHeight) { self._onSphereCreated(earth, textureWidth, textureHeight); }, this.options.tiling);
if (this.options.dragElement !== null) {
this.options.dragElement
.bind('mousedown vmousedown', function(e) {
self._mouseDragStart(e);
self.mousePressed = true;
})
.bind('mouseup vmouseup', function(e) {
self._mouseDragStop(e);
self.mousePressed = false;
})
.bind('mousemove vmousemove', function(e){
if (self.mousePressed) {
self._mouseDrag(e);
}
});
}
this._initLocations();
this._initFlights();
},
_initLocations: function() {
for (var key in this.options.locations) {
var location = this.options.locations[key];
location.visible = true;
this.options.onInitLocation(location, this);
}
},
_initFlights: function() {
for (var key in this.options.paths) {
var path = this.options.paths[key];
for (var key in path.flights) {
path.flights[key].visible = true;
this.options.onInitFlight(path.flights[key], this);
}
}
},
getSphereRadiusInPixel: function() {
return this.earth.getRadius() / 2;
},
_onSphereCreated: function(earth, textureWidth, textureHeight) {
var self = this;
this.textureWidth = textureWidth;
this.textureHeight = textureHeight;
this.earth = earth;
this.earth.init(this.options.sphere);
this.earth.turnBy = function(time) { return self._turnBy(time); };
var renderAnimationFrame = function(/* time */ time) {
/* time ~= +new Date // the unix time */
earth.renderFrame(time);
self._renderAnimationFrame(time);
self.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame);
};
this.renderAnimationFrameId = window.requestAnimationFrame(renderAnimationFrame);
},
destroy: function() {
window.cancelAnimationFrame(this.renderAnimationFrameId);
},
_renderAnimationFrame: function(time) {
var ry=90+this.options.sphere.tilt;
var rz=180+this.options.sphere.turn;
var RY = (90-ry);
var RZ = (180-rz);
var RX = 0,RY,RZ;
var rx=RX*Math.PI/180;
var ry=RY*Math.PI/180;
var rz=RZ*Math.PI/180;
//console.log(rx, ry, rz);
var r = this.getSphereRadiusInPixel();
var center = {
x: this.element.width() / 2,
y: this.element.height() / 2
}
for (var key in this.options.locations) {
var location = this.options.locations[key];
if (typeof location.delta === 'undefined') {
location.flatPosition = {x: location.x, y: location.y};
this.options.onRefreshLocation(location, location.x, location.y, this);
continue;
}
/*
WARNING: calculation of alphaAngle and deltaAngle is not exact
I had to create the _calibrated functions to modify the deltaAngle to make the result look good on
a spinning planet without rotation. It will totally bug with rotation!
* */
var progression = (((this.posVar + this.textureWidth * location.delta / (2 * Math.PI)) % this.textureWidth) / this.textureWidth);
var alphaAngle = progression * 2 * Math.PI;
var deltaAngle = this._calibrated(progression, location.alpha) * 2 * Math.PI;
var objAlpha = ry + location.alpha - Math.sin(alphaAngle / 2) * 0.15 * (location.alpha - Math.PI / 2) / (Math.PI / 4);
var objDelta = rz + deltaAngle;
var a = this._orbitalTo3d(objAlpha, objDelta, r);
var flatPosition = this._orthographicProjection(a);
if (a.x < 0 && !location.visible) {
this.options.onShowLocation(location, flatPosition.x, flatPosition.y, this);
}
if (a.x > 0 && location.visible) {
this.options.onHideLocation(location, flatPosition.x, flatPosition.y, this);
}
this.options.onRefreshLocation(location, flatPosition.x, flatPosition.y, this);
location.visible = a.x < 0;
location.position = a;
location.flatPosition = flatPosition;
location.rAlpha = objAlpha;
location.rDelta = objDelta;
}
if (this.flightsCtx !== null) {
this.flightsCtx.clearRect(0, 0, this.options.flightsCanvas.width(), this.options.flightsCanvas.height());
for (var key in this.options.paths) {
this._drawPath(this.options.paths[key], center, r);
}
}
},
_line_circle_intersection: function(A, B, C, r) {
var d = {
x: B.x - A.x,
y: B.y - A.y
};
var f = {
x: A.x - C.x,
y: A.y - C.y
};
var a = this._dot(d, d);
var b = 2 * this._dot(f, d);
var c = this._dot(f, f) - r * r;
var discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
return false;
} else {
discriminant = Math.sqrt(discriminant);
var t1 = (-b + discriminant) / (2 * a);
var t2 = (-b - discriminant) / (2 * a);
var sols = [];
if (t1 >= 0 && t1 <= 1) {
sols.push({
x:A.x + t1 * d.x,
y:A.y + t1 * d.y
});
}
if (t2 >= 0 && t2 <= 1) {
sols.push({
x:A.x + t2 * d.x,
y:A.y + t2 * d.y
});
}
return sols;
}
},
_dot: function(A, B) {
return A.x * B.x + A.y * B.y;
},
_drawPath: function(path, center, r) {
var originLocation = this.options.locations[path.origin];
var destinationLocation = this.options.locations[path.destination];
var dotSize = 50;
var spacing = 0.15;
if (typeof originLocation.delta === 'undefined' || typeof destinationLocation.delta === 'undefined') {
var pathVisible = originLocation.visible && destinationLocation.visible;
if (pathVisible) {
var flatDistance = this._distance(originLocation.flatPosition, destinationLocation.flatPosition);
var nb = flatDistance * 0.9 / 20;
// WARNING: we are drawing the paths on canvas, intensively using CPU. Could we gain by instead using SVG or the DOM ?
for (var i = 0; i < nb; i++) {
var fromFlatPosition = {
x: ((nb - i) / nb) * originLocation.flatPosition.x + (i / nb) * destinationLocation.flatPosition.x,
y: ((nb - i) / nb) * originLocation.flatPosition.y + (i / nb) * destinationLocation.flatPosition.y
};
var toFlatPosition = {
x: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.x + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.x,
y: Math.max(((nb - (i + 1)) / nb), 0) * originLocation.flatPosition.y + Math.min(((i + 1) / nb), 1) * destinationLocation.flatPosition.y
};
var diff = {
x: fromFlatPosition.x - toFlatPosition.x,
y: fromFlatPosition.y - toFlatPosition.y,
z: fromFlatPosition.z - toFlatPosition.z
};
fromFlatPosition.x -= diff.x * spacing;
fromFlatPosition.y -= diff.y * spacing;
fromFlatPosition.z -= diff.z * spacing;
toFlatPosition.x += diff.x * spacing;
toFlatPosition.y += diff.y * spacing;
toFlatPosition.z += diff.z * spacing;
this.flightsCtx.lineWidth = 3;
this.flightsCtx.beginPath();
this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.stroke();
}
}
for (var key in path.flights) {
var flight = path.flights[key];
var position = flight.destination == path.destination ? flight.position : (1 - flight.position);
var flightFlatPosition = {
x: (1 - position) * originLocation.flatPosition.x + position * destinationLocation.flatPosition.x,
y: (1 - position) * originLocation.flatPosition.y + position * destinationLocation.flatPosition.y
};
if (!flight.visible && pathVisible) {
this.options.onShowFlight(flight, this);
flight.visible = true;
}
if (flight.visible && !pathVisible) {
this.options.onHideFlight(flight, this);
flight.visible = false;
}
var angle = Math.atan2(destinationLocation.flatPosition.y - originLocation.flatPosition.y, destinationLocation.flatPosition.x - originLocation.flatPosition.x) + (flight.destination == path.destination ? 0 : Math.PI);
//console.log(flightAheadFlatPosition.y - flightFlatPosition.y);
this.options.onRefreshFlight(flight, flightFlatPosition.x, flightFlatPosition.y, angle, this);
}
return;
}
var locationsDistance = this._distance(originLocation.position, destinationLocation.position);
var middlePosition = {
x: 0,
y: 0,
z: 0
};
var radius = this._distance(originLocation.position, middlePosition);
var originP = {
delta: Math.atan2((originLocation.position.y - middlePosition.y), (originLocation.position.x - middlePosition.x)),
alpha: Math.acos((originLocation.position.z - middlePosition.z) / radius)
};
var destinationP = {
delta: Math.atan2((destinationLocation.position.y - middlePosition.y), (destinationLocation.position.x - middlePosition.x)),
alpha: Math.acos((destinationLocation.position.z - middlePosition.z) / radius)
};
if (Math.abs(originP.delta - destinationP.delta) > Math.PI) {
if ((originP.delta - destinationP.delta) > Math.PI) {
originP.delta -= 2 * Math.PI;
} else {
originP.delta += 2 * Math.PI;
}
}
if (path.sens) {
if (((originP.delta - destinationP.delta) > 0 ? 1 : -1) != path.sens) {
if (Math.abs(originP.delta - destinationP.delta) > Math.PI / 2) {
originP.delta += path.sens * 2 * Math.PI;
}
}
} else {
path.sens = (originP.delta - destinationP.delta) > 0 ? 1 : -1;
}
if (!path.nb) {
path.nb = Math.round(((locationsDistance / (2 * r)) * Math.PI * 2 * r + (1 - (locationsDistance / (2 * r))) * locationsDistance) / dotSize);
}
var nb = path.nb;
var maxDistance = 1.2;
for (var i = 0; i < nb; i++) {
var fromP = {
alpha: ((nb - i) / nb) * originP.alpha + (i / nb) * destinationP.alpha,
delta: ((nb - i) / nb) * originP.delta + (i / nb) * destinationP.delta
};
var toP = {
alpha: ((nb - 1 - i) / nb) * originP.alpha + ((i + 1) / nb) * destinationP.alpha,
delta: ((nb - 1 - i) / nb) * originP.delta + ((i + 1) / nb) * destinationP.delta
};
//console.log(i, fromP.alpha, fromP.delta, toP.alpha, toP.delta);
var fromPosition = this._orbitalTo3d(fromP.alpha, fromP.delta, -(Math.sin(Math.PI * i / nb) * (maxDistance - 1) + 1) * radius);
var toPosition = this._orbitalTo3d(toP.alpha, toP.delta, -(Math.sin(Math.PI * (i + 1) / nb) * (maxDistance - 1) + 1) * radius);
var diff = {
x: fromPosition.x - toPosition.x,
y: fromPosition.y - toPosition.y,
z: fromPosition.z - toPosition.z
};
fromPosition.x -= diff.x * spacing;
fromPosition.y -= diff.y * spacing;
fromPosition.z -= diff.z * spacing;
toPosition.x += diff.x * spacing;
toPosition.y += diff.y * spacing;
toPosition.z += diff.z * spacing;
fromPosition.x += middlePosition.x;
fromPosition.y += middlePosition.y;
fromPosition.z += middlePosition.z;
toPosition.x += middlePosition.x;
toPosition.y += middlePosition.y;
toPosition.z += middlePosition.z;
var fromFlatPosition = this._orthographicProjection(fromPosition);
var toFlatPosition = this._orthographicProjection(toPosition);
var fromDistanceCenter = this._distance(fromFlatPosition, center);
var toDistanceCenter = this._distance(toFlatPosition, center);
var fromVisible = true;
var toVisible = true;
if (fromPosition.x > 0) {
if (fromDistanceCenter <= r) {
fromVisible = false;
}
}
if (toPosition.x > 0) {
if (toDistanceCenter <= r) {
toVisible = false;
}
}
//console.log(i, fromVisible, toVisible);
if (!fromVisible && !toVisible) {
continue;
}
if (!fromVisible) {
var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r);
if (intersection.length == 0) {
continue;
}
fromFlatPosition = intersection[0];
}
if (!toVisible) {
var intersection = this._line_circle_intersection(fromFlatPosition, toFlatPosition, center, r);
if (intersection.length == 0) {
continue;
}
toFlatPosition = intersection[0];
}
this.flightsCtx.lineWidth = 3;
this.flightsCtx.beginPath();
this.flightsCtx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
this.flightsCtx.moveTo(fromFlatPosition.x + this.options.flightsCanvasPosition.x, fromFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.lineTo(toFlatPosition.x + this.options.flightsCanvasPosition.x, toFlatPosition.y + this.options.flightsCanvasPosition.y);
this.flightsCtx.stroke();
}
for (var key in path.flights) {
var flight = path.flights[key];