Rumah >hujung hadapan web >tutorial js >Menggambarkan aliran twitter di VR dengan tiga.js dan nod
pernah membincangkan semua asas -asas untuk membangunkan pengalaman web realiti maya dalam artikel SitePoint yang membawa VR ke web dengan Google Cardboard dan Three.js, jadi jika anda baru untuk keseluruhan idea ini - baca yang pertama dan datang Kembali. Demo ini menggunakan asas yang sama.
Demo Kami akan membina akan menonton aliran Twitter secara langsung untuk kata kunci. Apabila seseorang tweet keluar sementara ia menonton aliran, ia akan membawa "menara" zarah bersinar yang mewakili berapa lama tweet itu. Demo ini khususnya akan mencari sebutan perkataan "pizza". Mengapa pizza anda bertanya? Saya sedang mencari istilah yang tidak disebutkan selalunya "bieber" tetapi lebih kerap daripada "boxcar racing hyenas". Singkatnya, istilah terbaik adalah yang agak kerap sehingga mereka akan muncul semasa anda menonton, tetapi tidak begitu kerap sehingga mereka melalui beratus -ratus detik. Pizza adalah salah satu daripada mereka.
Takeaways Key
mahu mencubanya dalam tindakan? Saya mempunyai versi berjalan yang dihoskan di sini: VR Twitter World.
Kod pelayan kami
pelayan penuh agak pendek dan kelihatan seperti:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80, </span> io <span>= require('socket.io')(server), </span> config <span>= require('./config.json'), </span> <span>Twitter = require('node-tweet-stream'), </span> t <span>= new Twitter(config); </span> app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>}); </span> app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>}); </span> app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>}); </span> server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>}); </span> t<span>.track('pizza'); </span>t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>}); </span> t<span>.on('error', function (err) { </span> <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err); </span><span>});</span>baris pertama kami menyediakan pelayan menggunakan rangka kerja Node Express. Ia adalah set yang agak mudah yang menarik dalam semua kebergantungan kami dan menyediakan pembolehubah aplikasi untuk kami mengakses fungsi pelayan kami. Port menetapkan pelabuhan mana yang kami mahu pelayan kami dijalankan (Process.env.port adalah pembolehubah pelayan beberapa hosting set ups seperti Heroku akan ditakrifkan).
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80, </span> io <span>= require('socket.io')(server), </span> config <span>= require('./config.json'), </span> <span>Twitter = require('node-tweet-stream'), </span> t <span>= new Twitter(config); </span> app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>}); </span> app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>}); </span> app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>}); </span> server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>}); </span> t<span>.track('pizza'); </span>t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>}); </span> t<span>.on('error', function (err) { </span> <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err); </span><span>});</span>
Kemudian kami menyediakan pembolehubah IO sementara pada masa yang sama memulakan fungsi pelayan Socket.io kami, melampirkannya ke pelayan ekspres yang kami sediakan di atas:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80,</span>
Pembolehubah konfigurasi adalah cara yang baik untuk menjaga kekunci pengesahan Twitter aplikasi dan token akses dalam fail mereka sendiri. Untuk hidup melihat aliran Twitter, kami akan menggunakan modul NPM yang dipanggil aliran nod-tweet yang menyediakan semua fungsi yang kami perlukan. Kami menetapkan objek untuk akses Twitter kami dan semua fungsi yang berkaitan dengan pembolehubah T, lulus dalam konfigurasi kami untuk membuktikan kami dibenarkan mengaksesnya.
io <span>= require('socket.io')(server),</span>
Jika anda tidak mempunyai kunci Twitter untuk akses ke API Twitter, jangan takut! Anda hanya perlu mendaftarkan aplikasi dengan Twitter. Pergi ke halaman Pengurusan Aplikasi Twitter, log masuk dengan kelayakan Twitter anda dan kemudian klik "Buat Aplikasi Baru".
Sebaik sahaja anda mempunyai aplikasi, anda boleh mendapatkan kunci dan token akses anda dengan mengklik pautan "Kekunci dan Akses" yang akan muncul di halaman pengurusan aplikasi anda. Jika anda tidak dapat menemuinya, ia akan berada di URL: https://apps.twitter.com/app/0000000/keys (menggantikan 0000000 dengan id aplikasi anda).
Kemudian, buat fail pada tahap yang sama seperti index.html yang dipanggil config.json. Di dalamnya, tambahkan yang berikut dengan nilai aplikasi anda sendiri:
config <span>= require('./config.json'), </span><span>Twitter = require('node-tweet-stream'), </span>t <span>= new Twitter(config),</span>
Selanjutnya dalam fail index.js kami, kami menyediakan panggilan ke akar pelayan kami untuk memuat /public/index.html:
<span>{ </span> <span>"consumer_key": "YOURKEY", </span> <span>"consumer_secret": "YOURKEYSECRET", </span> <span>"token": "YOURTOKEN", </span> <span>"token_secret": "YOURTOKENSECRET" </span><span>}</span>
kami juga menyampaikan fail statik lain dalam direktori awam di pelayan kami:
app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>});</span>
Jika kita mempunyai ralat, kita log ralat itu dalam konsol pelayan kami dan mengembalikan ralat 500:
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>});</span>
baris berikut memulakan pelayan kami berjalan dengan semua tetapan di atas.
app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>});</span>
Akhirnya, kami menyediakan fungsi pelayan khusus Twitter kami. Kami menggunakan fungsi trek () untuk menentukan kata kunci mana yang kami ingin menjejaki aliran kandungan Twitter yang semakin berkembang.
server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>});</span>
Kami kemudian menyediakan fungsi panggil balik untuk dijalankan pada bila-bila masa modul nod-tweet-stream menjumpai tweet dengan kata kunci itu. Jika ia melihatnya, kami log masuk dalam log konsol pelayan kami (ini adalah pilihan, anda boleh mengeluarkan ini jika anda mahu) dan kemudian memancarkan tweet itu sebagai acara Socket.io kepada mana -mana pelanggan yang bersambung.
t<span>.track('pizza');</span>Jika kita mempunyai ralat untuk apa -apa sebab dengan API Twitter kami, ia akan dilog masuk ke log pelayan kami:
t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>});</span>Semua kebergantungan dan butiran pelayan kami disimpan dalam pakej.json seperti semua aplikasi nod. Sekiranya anda baru untuk node.js, anda mungkin mahu membaca sedikit mengenai apa yang dimaksudkan: pakej.json.
Kod akhir depan kami bermula dengan persediaan yang sama dari membawa VR ke web dengan Google Cardboard dan artikel tiga.js - adegan tiga.js yang kami paparkan melalui kesan stereoskopik, membawa adegan kami ke dalam pandangan VR. Untuk memastikan ini pendek dan manis, saya tidak akan menutupi bit yang sama dengan demo sebelumnya dari artikel itu. Jika anda tidak pasti apa -apa yang saya tidak jelaskan di sini, periksa artikel terdahulu untuk maklumat.
Satu -satunya fail JS baru yang akan kami tambahkan berbanding dengan asas kami yang terdahulu ialah fail socket.io JavaScript kami. Ia adalah satu pelapik yang mudah:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80, </span> io <span>= require('socket.io')(server), </span> config <span>= require('./config.json'), </span> <span>Twitter = require('node-tweet-stream'), </span> t <span>= new Twitter(config); </span> app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>}); </span> app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>}); </span> app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>}); </span> server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>}); </span> t<span>.track('pizza'); </span>t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>}); </span> t<span>.on('error', function (err) { </span> <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err); </span><span>});</span>
Untuk mengakses fungsi dari socket.io, semua yang kita perlukan adalah untuk menetapkan fungsi tersebut kepada pembolehubah IO, seperti yang anda lihat sedikit lebih jauh dalam fail index.html kami:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80,</span>
Kami kemudian menyediakan pembolehubah untuk "menara" kami (pada dasarnya set menegak zarah kami yang mewakili tweet). Semua menara kami disimpan dalam objek Three.Object3D yang dipanggil TweTtowers. Ini adalah objek kontena yang membolehkan kita menjejaki semua menara kami:
io <span>= require('socket.io')(server),</span>ParticleTexture dan Particlematerial adalah pembolehubah kita yang akan mewakili bagaimana zarah kita akan kelihatan:
config <span>= require('./config.json'), </span><span>Twitter = require('node-tweet-stream'), </span>t <span>= new Twitter(config),</span>
MaxtowerCount adalah bilangan maksimum menara yang kita mahu dapat dilihat di tempat kejadian - jika ini ditetapkan terlalu tinggi, kita boleh berakhir dengan pengalaman yang laggy. Saya telah menetapkannya kepada 6000 kerana ini menetapkan zarah maksimum untuk sekitar satu juta. Nombor yang berpatutan pada pendapat saya!
<span>{ </span> <span>"consumer_key": "YOURKEY", </span> <span>"consumer_secret": "YOURKEYSECRET", </span> <span>"token": "YOURTOKEN", </span> <span>"token_secret": "YOURTOKENSECRET" </span><span>}</span>
Range adalah betapa besar kawasan di sekitar penonton yang kita mahu menara ini diletakkan. Menara akan diletakkan di tempat rawak di tempat kejadian, jadi ini mengehadkan sejauh mana mereka semua diletakkan. Saya dapati ia adalah pengalaman yang lebih baik dengan mereka lebih dekat dengan pengguna. Sekiranya mereka jauh dari pengguna, ia kelihatan seperti tidak banyak (walaupun terdapat beribu -ribu zarah!). Saya menetapkannya kepada 100:
app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>});</span>fungsi init kami
Kami mentakrifkan imej particleTexture kami untuk menjadi png yang dipanggil zarah-baru.png yang kami ada dalam folder awam kami:
app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>});</span>kami menyelesaikan fungsi init () dengan menambahkan bekas TweTtowers kami ke tempat kejadian kami. Dengan ini di tempat kejadian, kami tidak perlu bimbang tentang menambahkan mana -mana menara kami terus ke tempat kejadian, kami hanya menambahnya ke objek TweTtowers kami secara langsung.
app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>});</span>Reacting to Tweets
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80, </span> io <span>= require('socket.io')(server), </span> config <span>= require('./config.json'), </span> <span>Twitter = require('node-tweet-stream'), </span> t <span>= new Twitter(config); </span> app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>}); </span> app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>}); </span> app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>}); </span> server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>}); </span> t<span>.track('pizza'); </span>t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>}); </span> t<span>.on('error', function (err) { </span> <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err); </span><span>});</span>
Kod tindak balas adalah panggilan kepada fungsi yang dipanggil GenerateTower () yang akan menambah menara ke tempat kejadian kami yang mewakili tweet itu. Kami menyampaikannya empat nilai:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80,</span>
fungsi generatetower () kami sendiri bermula dengan menentukan pemboleh ubah menara. Ini adalah objek tiga.Geometry yang akan mengandungi kedudukan semua zarah kita di dalam menara. Menjaga semua mata yang dikesan dalam satu objek geometri boleh membantu mengekalkan masa pemprosesan ke bawah, kerana tiga.js hanya perlu menjejaki setiap objek menara dan mata, bukannya pelbagai zarah bebas. Kemudian dalam kod, kami akan memberikan geometri ke objek tiga.pointCloud yang dapat mentafsir mata -mata tersebut ke dalam zarah kami.
io <span>= require('socket.io')(server),</span>
Kami kemudian menubuhkan objek JavaScript yang dipanggil Particlemovements yang menyimpan di mana zarah -zarah kita akan bermula dan selesai di dalam menara, bersama -sama dengan sejauh mana mereka akan menjadi (nilai yang kami lalui sebelumnya):
config <span>= require('./config.json'), </span><span>Twitter = require('node-tweet-stream'), </span>t <span>= new Twitter(config),</span>
Pembolehubah CurrentCoords menjejaki kedudukan terakhir zarah dalam menara. Kami memulakannya pada 0,0,0. Penjelasan permulaan di mana menara akan diletakkan dihuraikan dari panggilan fungsi lebih awal. Sekiranya kita tidak mempunyai koordinat permulaan dari panggilan fungsi, kita memulakannya sama seperti CurrentCoords:
<span>{ </span> <span>"consumer_key": "YOURKEY", </span> <span>"consumer_secret": "YOURKEYSECRET", </span> <span>"token": "YOURTOKEN", </span> <span>"token_secret": "YOURTOKENSECRET" </span><span>}</span>
Kami kemudian melangkah melalui saiz menara kami untuk membuat setiap zarah. Kami menetapkan koordinat semasa untuk Y untuk meningkat dengan nilai kelajuan kami didarabkan oleh i. Nilai X dan Z kami kekal di tempat permulaan mereka kerana kami hanya bergerak ke atas.
app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>});</span>
Dengan koordinat yang ditakrifkan untuk zarah ini, kami melampirkan kedudukan zarah itu sebagai puncak dalam objek towergeometry kami:
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80, </span> io <span>= require('socket.io')(server), </span> config <span>= require('./config.json'), </span> <span>Twitter = require('node-tweet-stream'), </span> t <span>= new Twitter(config); </span> app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>}); </span> app<span>.get(<span>/<span>^(.+)$</span>/</span>, function(req<span>, res</span>) { </span> res<span>.sendFile(__dirname + '/public/' + req.params[0]); </span><span>}); </span> app<span>.use(function(err<span>, req, res, next</span>) { </span> <span>console.error(err.stack); </span> res<span>.status(500).send('Something broke!'); </span><span>}); </span> server<span>.listen(port, function() { </span> <span>console.log('Listening on ' + port); </span><span>}); </span> t<span>.track('pizza'); </span>t<span>.on('tweet', function(tweet){ </span> <span>console.log('Roger that. Tweets incoming!'); </span> <span>console.log(tweet); </span> io<span>.emit('tweet', tweet); </span><span>}); </span> t<span>.on('error', function (err) { </span> <span>console.log('Brace yourself! We are goin doooowwwwwwnnnnnnnn! ', err); </span><span>});</span>
yang memastikan kedudukan zarah kami ditetapkan dengan betul. Seterusnya, kita menentukan apa yang zarah di menara ini akan kelihatan seperti dalam pembolehubah particlematerial. Zarah kami akan diletakkan dalam objek tiga.pointCloud dan dengan itu gaya mereka, kami akan menggunakan bahan tiga.
<span>var express = require('express'), </span> app <span>= express(), </span> server <span>= require('http').createServer(app), </span> port <span>= process.env.PORT || 80,</span>
io <span>= require('socket.io')(server),</span>Kami menambah menara itu ke objek koleksi TweTtowers kami dan kemudian periksa untuk melihat berapa banyak menara di tempat kejadian. Sekiranya kita mempunyai lebih banyak menara daripada maksimum yang dibenarkan, kita menyembunyikan yang tertua untuk mengurangkan beban pada peranti. Sekiranya anda mempunyai masalah prestasi, kemungkinan mereka akan menjadi lebih baik jika anda mengurangkan maxtowercount!
config <span>= require('./config.json'), </span><span>Twitter = require('node-tweet-stream'), </span>t <span>= new Twitter(config),</span>menjalankan kod kami
<span>{ </span> <span>"consumer_key": "YOURKEY", </span> <span>"consumer_secret": "YOURKEYSECRET", </span> <span>"token": "YOURTOKEN", </span> <span>"token_secret": "YOURTOKENSECRET" </span><span>}</span>kemudian jalankannya:
app<span>.get('/', function(request<span>, response</span>) { </span> response<span>.sendFile(__dirname + '/public/index.html'); </span><span>});</span>Untuk menguji ini pada telefon pintar anda, anda perlu memastikan telefon pintar anda berada di rangkaian tempatan yang sama dan cari alamat IP komputer anda, atau gunakan perkhidmatan terowong seperti NGROK (saya tutup cara menggunakan NGROK dalam artikel tersebut Semasa mengakses localhost dari mana -mana sahaja).
Anda juga boleh menjadi tuan rumah pelayan nod di suatu tempat. Saya secara peribadi menggunakan Heroku, namun ini adalah keutamaan peribadi.
Sebaik sahaja anda mempunyai pelayan di suatu tempat dan berjalan, buka Chrome untuk mudah alih dan lawati! Pakai kadbod Google anda atau alat dengar lain yang serupa dan anda harus melihat pengalaman yang selepas setengah minit atau lebih seperti ini jika anda melihat:
Saya juga mendapat demo lain di sini di SitePoint yang menggunakan konsep yang sama tetapi sebaliknya membawa mereka ke dalam pengalaman realiti tambahan. Sekiranya anda berminat, menapis realiti dengan JavaScript dan Google Cardboard meneroka mengambil kamera dari telefon pintar anda dan menambahkan penapis kepadanya, dan menambah realiti dalam penyemak imbas dengan awe.js meneroka berjalan sepanjang jalan dan menambah unsur -unsur ke dalam bidang pandangan anda melalui melalui medan anda melalui Gabungan tiga.js dan awe.js!
jika anda mengambil cabaran untuk menyusun visualisasi VR anda sendiri dari demo dalam artikel ini (atau menggabungkannya dengan unsur -unsur dari contoh AR yang disebutkan), tinggalkan nota dalam komen atau berhubung dengan saya di twitter (@thatpatrickguy), saya akan keluar alat dengar saya dan lihat!
Menyediakan Twitter untuk laman web melibatkan beberapa langkah. Pertama, anda perlu membuat aplikasi Twitter di laman pemaju Twitter. Selepas membuat permohonan, anda akan menerima satu set kunci dan token. Ini digunakan untuk mengesahkan aplikasi anda dengan Twitter. Anda kemudian perlu memasang API JavaScript Twitter di laman web anda. API ini membolehkan laman web anda berinteraksi dengan Twitter, membolehkan ciri-ciri seperti butang tweet dan tweet tertanam. Perpustakaan JavaScript yang digunakan untuk membuat dan memaparkan grafik komputer 3D animasi dalam pelayar web. Ia menggunakan WebGL untuk menjadikan grafik. Perpustakaan menyediakan satu set objek dan kaedah yang menjadikannya lebih mudah untuk mewujudkan adegan 3D yang kompleks, termasuk kamera, lampu, bahan, dan geometri.
Untuk menggunakan tiga.js pada node.js, anda perlu memasang pakej 'tiga' menggunakan NPM, Pengurus Pakej Node.js. Setelah dipasang, anda boleh memerlukan modul 'tiga' dalam skrip Node.js anda. Anda kemudian boleh menggunakan API Tiga.js untuk membuat grafik 3D.Bagaimana saya boleh menggunakan aplikasi tiga.js saya ke web? Aplikasi tiga.js ke web melibatkan pembungkusan fail aplikasi anda dan memuat naiknya ke pelayan web. Anda boleh menggunakan alat seperti Webpack untuk membungkus fail JavaScript anda, dan perkhidmatan seperti halaman GitHub atau Netlify untuk menjadi tuan rumah permohonan anda. Sebaik sahaja dikerahkan, aplikasi anda boleh diakses oleh sesiapa sahaja dengan pelayar web.
Atas ialah kandungan terperinci Menggambarkan aliran twitter di VR dengan tiga.js dan nod. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!