Tekstura z canvas do webgl
Ten przykład to "making of" projektu obracającej się kuli ziemskiej z wygenerowanej w locie tekstury z elementu canvas. W przykładzie wykorzystujemy następujące biblioteki: jVectorMap - tworzenie wektorowych map, canvg - parser SVG, tworzy canvasa z kodu svg oraz three.js - do obsługi webgl. Pokazuję tutaj jak połączyć trzy biblioteki w celu uzyskania ciekawego efektu. Kod html przykładu:
<!DOCTYPE html> <html> <head> <title>Canvas do webgl</title> <link rel="stylesheet" href="jquery-jvectormap-1.2.2.css" type="text/css" media="screen"/> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="jquery-jvectormap-1.1.1.min.js"></script> <script src="jquery-jvectormap-world-mill-en.js"></script> <script type="text/javascript" src="canvg-1.3/rgbcolor.js"></script> <script type="text/javascript" src="canvg-1.3/StackBlur.js"></script> <script type="text/javascript" src="canvg-1.3/canvg.js"></script> <script type="text/javascript" src="three.min.js"></script> <script src="Detector.js"></script> </head> <body> <button id="create">Create</button> <div id="world-map" style="width: 2048px; height: 1024px;position:absolute;"></div> <div id="svg"></div> <canvas id="canvas" width="2048px" height="1024px" style="display:none;"></canvas> <div id="webgl"></div> <script src="main.js"></script> </body> </html>Załączamy w nim odpowiednie biblioteki oraz plik main.js z naszym kodem. Przycisk create będzie służył do stworzenia obracającej się kuli. Div o id world-map zawiera wekorową mapę jVectorMap, na której będziemy zaznaczać kraje. Po kliknięciu na create utworzy się kula, której teksturą będzie canvas utworzony na bazie jVectorMap.
Poniżej zawartość pliku main.js.
$(function() { var vectorMap = $('#world-map').vectorMap({ regionStyle: { hover: { fill: '#c6f9ff' }, selected: { fill: '#41b6c4' } }, selectedRegions: ['PL','DE','ES'], regionsSelectable: true }); $('#create').on('click', function() { createCanv(); $('#world-map').hide(); createWebgl(); return false; }); function createCanv() { var svg = $('.jvectormap-container').html(); var svg2 = svg.replace(/<div(.*)<\/div>/, ''); var rect = '<rect width="2048" height="1024" style="fill:rgb(80,80,80);" />'; var svg3 = svg2.replace(/(<svg.*?>)/,'$1'+rect); canvg(document.getElementById('canvas'), svg3, { ignoreMouse: false, ignoreAnimation: false }); } function createWebgl() { //webgl part var webglEl = document.getElementById('webgl'); if (!Detector.webgl) { Detector.addGetWebGLMessage(webglEl); return; } var width = 1200, height = 800; // Earth params var radius = 0.5, segments = 32, rotation = 6; var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(45, width / height, 0.01, 1000); camera.position.z = 1.5; var renderer = new THREE.WebGLRenderer(); renderer.setSize(width, height); scene.add(new THREE.AmbientLight(0x333333)); var light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(5,3,5); scene.add(light); var bitmap = document.getElementById('canvas'); var texture = new THREE.Texture(bitmap); texture.needsUpdate = true; var sphere = new THREE.Mesh( new THREE.SphereGeometry(radius, segments, segments), new THREE.MeshPhongMaterial({ map: texture }) ); texture.needsUpdate = true; sphere.rotation.y = rotation; scene.add(sphere); webglEl.appendChild(renderer.domElement); render(); function render() { sphere.rotation.y += 0.005; requestAnimationFrame(render); renderer.render(scene, camera); } } });
Funkcja createCanv jest odpowiedzialna za stworzenie odpowiedniego canvasa, którego wykorzystujemy w funkcji createWebgl jako teksturę kuli. W funkcji createCanv na podstawie kodu svg wygenerowanego przez jVectorMap za pomocą canvg tworzymy element canvas wyglądający dokładnie tak samo jak nasza wektorowa mapa. Na koniec w ten sposób wygenerowany obraz wykorzystujemy jako tesktura dla obracającej się kuli w funkcji createWebgl. Demo jVectorMap + canvg + three.js