add preview + update
This commit is contained in:
parent
47d14f6fad
commit
2043bfbf13
6 changed files with 436 additions and 16 deletions
|
|
@ -340,12 +340,26 @@ summary {
|
||||||
|
|
||||||
.delete {
|
.delete {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
left: 0;
|
||||||
|
padding: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.intro {
|
.intro {
|
||||||
top: 40%;
|
top: 40%;
|
||||||
transform: translate(-50%);
|
transform: translate(-50%);
|
||||||
|
|
|
||||||
32
server.js
32
server.js
|
|
@ -57,6 +57,13 @@ fastify.get("/", function (request, reply) {
|
||||||
reply.view("/src/pages/parade.html", {});
|
reply.view("/src/pages/parade.html", {});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//get '/preview/:foldername'
|
||||||
|
fastify.get("/preview/:foldername", function (request, reply) {
|
||||||
|
//
|
||||||
|
//request.params.foldername
|
||||||
|
reply.view("/src/pages/preview.html", {});
|
||||||
|
});
|
||||||
|
|
||||||
//get '/entry', '/entry/', '/en/entry', '/en/entry/'
|
//get '/entry', '/entry/', '/en/entry', '/en/entry/'
|
||||||
["/entry", "/entry/", "/en/entry", "/en/entry/"].forEach(function(item) {
|
["/entry", "/entry/", "/en/entry", "/en/entry/"].forEach(function(item) {
|
||||||
fastify.get(item, async function (request, reply) {
|
fastify.get(item, async function (request, reply) {
|
||||||
|
|
@ -105,7 +112,30 @@ fastify.get("/entries", async function (request, reply) {
|
||||||
//get list
|
//get list
|
||||||
let list = await fs.readdir('/media/storage/public/sound-parade/');
|
let list = await fs.readdir('/media/storage/public/sound-parade/');
|
||||||
|
|
||||||
reply.send({ list: list });
|
reply.send(list);
|
||||||
|
});
|
||||||
|
|
||||||
|
//get '/fields'
|
||||||
|
fastify.get("/fields", async function (request, reply) {
|
||||||
|
|
||||||
|
//get list
|
||||||
|
let list = await fs.readdir('/media/storage/public/sound-parade/');
|
||||||
|
//list.reverse();
|
||||||
|
|
||||||
|
// console.log(list);
|
||||||
|
|
||||||
|
let folders = [];
|
||||||
|
for (const item of list) {
|
||||||
|
var fields = JSON.parse((await fs.readFile('/media/storage/public/sound-parade/' + item + '/fields.json')).toString('utf8'));
|
||||||
|
folders.push({
|
||||||
|
foldername: item,
|
||||||
|
group: fields.group,
|
||||||
|
title: fields.title,
|
||||||
|
comment: fields.comment,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
reply.send(folders);
|
||||||
});
|
});
|
||||||
|
|
||||||
//get '/delete'
|
//get '/delete'
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/entry.css" />
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
|
@ -59,14 +58,15 @@
|
||||||
Place<br/>
|
Place<br/>
|
||||||
<a href="https://walkingtowardstheflow.xyz">walkingtowardstheflow.xyz</a>, <a href="https://www.youtube.com/c/franceencoree">France en Corée - YouTube channel</a>
|
<a href="https://walkingtowardstheflow.xyz">walkingtowardstheflow.xyz</a>, <a href="https://www.youtube.com/c/franceencoree">France en Corée - YouTube channel</a>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
artists<br/>
|
||||||
|
<a href="https://dianaband.info" target="_blank">diana band</a> X <a href="https://cgyoon.kr/" target="_blank">Choong-geun Yoon</a> (Inquiry: wonjung24@gmail.com)
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Parade Composition<br/>
|
Parade Composition<br/>
|
||||||
Flock0 promises — Flock1 flags — Flock2 bodies — Flock3 objects — Flock4 someone
|
Flock0 promises — Flock1 flags — Flock2 bodies — Flock3 objects — Flock4 someone
|
||||||
</p>
|
</p>
|
||||||
<p>
|
|
||||||
Inquiry<br/>
|
|
||||||
wonjung24@gmail.com
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="participation">
|
<section class="participation">
|
||||||
|
|
@ -148,6 +148,7 @@
|
||||||
<li>Title | <div class="title">{{this.title}}</div></li><hr>
|
<li>Title | <div class="title">{{this.title}}</div></li><hr>
|
||||||
<li>Desc. | <div class="comment">{{this.comment}}</div></li><hr>
|
<li>Desc. | <div class="comment">{{this.comment}}</div></li><hr>
|
||||||
</ul>
|
</ul>
|
||||||
|
<button class="preview" type="button" onclick="javascript:window.open('/preview/{{this.foldername}}', '_blank');">Preview</button>
|
||||||
<button class="delete" type="button" onclick="del(this)">Delete</button>
|
<button class="delete" type="button" onclick="del(this)">Delete</button>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="/entry.css" />
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
|
@ -61,12 +60,12 @@
|
||||||
<a href="https://walkingtowardstheflow.xyz">walkingtowardstheflow.xyz</a><br><a href="https://www.youtube.com/c/franceencoree">주한프랑스대사관 문화과 유튜브 채널</a>
|
<a href="https://walkingtowardstheflow.xyz">walkingtowardstheflow.xyz</a><br><a href="https://www.youtube.com/c/franceencoree">주한프랑스대사관 문화과 유튜브 채널</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
퍼레이드 구성<br/>
|
작가<br/>
|
||||||
무리0 약속들 — 무리1 깃발들 — 무리2 신체들 — 무리3 사물들 — 무리4 누구들
|
<a href="https://dianaband.info" target="_blank">다이애나밴드</a> X <a href="https://cgyoon.kr/" target="_blank">윤충근</a> (문의: wonjung24@gmail.com)
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
문의<br/>
|
퍼레이드 구성<br/>
|
||||||
wonjung24@gmail.com
|
무리0 약속들 — 무리1 깃발들 — 무리2 신체들 — 무리3 사물들 — 무리4 누구들
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -150,6 +149,7 @@
|
||||||
<li>제목 | <div class="title">{{this.title}}</div></li><hr>
|
<li>제목 | <div class="title">{{this.title}}</div></li><hr>
|
||||||
<li>묘사 | <div class="comment">{{this.comment}}</div></li><hr>
|
<li>묘사 | <div class="comment">{{this.comment}}</div></li><hr>
|
||||||
</ul>
|
</ul>
|
||||||
|
<button class="preview" type="button" onclick="javascript:window.open('/preview/{{this.foldername}}', '_blank');">미리보기</button>
|
||||||
<button class="delete" type="button" onclick="del(this)">삭제</button>
|
<button class="delete" type="button" onclick="del(this)">삭제</button>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@
|
||||||
var roomsel = createDiv();
|
var roomsel = createDiv();
|
||||||
roomsel.class("roomsel");
|
roomsel.class("roomsel");
|
||||||
var b = createButton("시작하기 Start!", 1);
|
var b = createButton("시작하기 Start!", 1);
|
||||||
var d = createDiv("흐름을 향하여 걷는 Walking towards the Flow");
|
var d = createDiv("<a href='/entry'>흐름을 향하여 걷는 Walking towards the Flow</a>");
|
||||||
d.class("title");
|
d.class("title");
|
||||||
b.mouseClicked(function() {
|
b.mouseClicked(function() {
|
||||||
silence.start();
|
silence.start();
|
||||||
|
|
@ -136,17 +136,17 @@
|
||||||
socket.on("post", async function(post) {
|
socket.on("post", async function(post) {
|
||||||
|
|
||||||
console.log(post);
|
console.log(post);
|
||||||
var resp = await new Promise((resolve, reject) => {
|
var list = await new Promise((resolve, reject) => {
|
||||||
loadJSON("/entries", (json) => resolve(json));
|
loadJSON("/entries", (json) => resolve(json));
|
||||||
})
|
})
|
||||||
console.log(resp.list);
|
console.log(list);
|
||||||
|
|
||||||
// var object = post.object;
|
// var object = post.object;
|
||||||
var object = {
|
var object = {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"type": "abc",
|
"type": "abc",
|
||||||
"src": "https://p.dianaband.info/public/sound-parade/" + resp.list[post] + "/pixels.png",
|
"src": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/pixels.png",
|
||||||
"audio": "https://p.dianaband.info/public/sound-parade/" + resp.list[post] + "/audio.mp3",
|
"audio": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/audio.mp3",
|
||||||
"alt": "알트",
|
"alt": "알트",
|
||||||
"size": {
|
"size": {
|
||||||
"base": 40,
|
"base": 40,
|
||||||
|
|
|
||||||
375
src/pages/preview.html
Normal file
375
src/pages/preview.html
Normal file
|
|
@ -0,0 +1,375 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>흐름을 향하여 걷는</title>
|
||||||
|
<link rel="stylesheet" href="/default.css" />
|
||||||
|
<style>
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="/js/p5-v1.1.9.min.js"></script>
|
||||||
|
<script src="/js/socket-v2.3.0.io.slim.js"></script>
|
||||||
|
<script src="/js/Tone-14.8.36.min.js"></script>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@500&display=swap" rel="stylesheet" />
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="bg"></div>
|
||||||
|
<div class="content">
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
// // force https
|
||||||
|
// var http_confirm = location.href.split(":")[0];
|
||||||
|
// if (http_confirm == "http") {
|
||||||
|
// window.location.replace("https://" + location.host);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//--> https://gist.github.com/mudge/5830382#gistcomment-3398873 + modified trigger to accentp an arg.
|
||||||
|
function EventEmitter() {
|
||||||
|
const eventRegister = {};
|
||||||
|
|
||||||
|
const on = (name, fn) => {
|
||||||
|
if (!eventRegister[name]) eventRegister[name] = [];
|
||||||
|
eventRegister[name].push(fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
const trigger = (name, arg = undefined) => {
|
||||||
|
if (!eventRegister[name]) return false;
|
||||||
|
eventRegister[name].forEach((fn) => fn.call(this, arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
const off = (name, fn) => {
|
||||||
|
if (eventRegister[name]) {
|
||||||
|
const index = eventRegister[name].indexOf(fn);
|
||||||
|
if (index >= 0) eventRegister[name].splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
on, trigger, off
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//get preview target foldername
|
||||||
|
var foldername = "";
|
||||||
|
var urlparts = window.location.pathname.replace(/\/\s*$/,'').split('/');
|
||||||
|
foldername = urlparts[2]; // the server's route will guarantee urlparts[2] existence.
|
||||||
|
console.log(foldername);
|
||||||
|
|
||||||
|
var playing = true;
|
||||||
|
|
||||||
|
//set-up a preview stage
|
||||||
|
async function orchestra() {
|
||||||
|
|
||||||
|
//collect info.
|
||||||
|
var entries = await new Promise(async (resolve, reject) => resolve((await fetch("/entries")).json()));
|
||||||
|
var fields = await new Promise(async (resolve, reject) => resolve((await fetch("/fields")).json()));
|
||||||
|
var group = fields[entries.findIndex((e) => e == foldername)].group;
|
||||||
|
var members = fields.filter(obj => obj.group == group);
|
||||||
|
var midx = members.findIndex((e) => e.foldername == foldername);
|
||||||
|
//
|
||||||
|
function mtrig(m) {
|
||||||
|
//
|
||||||
|
m = m % members.length;
|
||||||
|
//
|
||||||
|
var idx = entries.findIndex((e) => e == members[m].foldername);
|
||||||
|
if (idx >= 0) socket.trigger('post', idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
//now, let's orchestrate!
|
||||||
|
var time = 0;
|
||||||
|
Tone.Transport.schedule((t) => mtrig(midx - 1), time);
|
||||||
|
time = time + 12 + Math.random()*(4);
|
||||||
|
console.log(time);
|
||||||
|
Tone.Transport.schedule((t) => mtrig(midx), time);
|
||||||
|
time = time + 16 + Math.random()*(4);
|
||||||
|
console.log(time);
|
||||||
|
Tone.Transport.schedule((t) => mtrig(midx + 1), time);
|
||||||
|
time = time + 5 + Math.random()*(4);
|
||||||
|
console.log(time);
|
||||||
|
Tone.Transport.schedule((t) => mtrig(midx + 2), time);
|
||||||
|
time = time + 5 + Math.random()*(4);
|
||||||
|
console.log(time);
|
||||||
|
Tone.Transport.schedule((t) => mtrig(midx), time);
|
||||||
|
time = time + 70;
|
||||||
|
console.log(time);
|
||||||
|
Tone.Transport.schedule((t) => {
|
||||||
|
playing = false;
|
||||||
|
});
|
||||||
|
//
|
||||||
|
Tone.Transport.start();
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
setTimeout(() => {
|
||||||
|
socket.trigger('connect');
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
//
|
||||||
|
//var socket = io(location.host);
|
||||||
|
var socket = new EventEmitter();
|
||||||
|
var n = 0;
|
||||||
|
var fr = 20;
|
||||||
|
var arr = [];
|
||||||
|
var looper;
|
||||||
|
var score;
|
||||||
|
var logo;
|
||||||
|
var silence;
|
||||||
|
var clap;
|
||||||
|
|
||||||
|
//promisify -> new Tone.Player
|
||||||
|
function AudioImport(url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var audio = new Tone.Player(url, () => resolve(audio));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setup() {
|
||||||
|
noCanvas();
|
||||||
|
if (windowWidth > 1500 && windowWidth > windowHeight) {
|
||||||
|
fr = 30;
|
||||||
|
} else {
|
||||||
|
fr = 20;
|
||||||
|
}
|
||||||
|
frameRate(fr);
|
||||||
|
|
||||||
|
//p5 'draw()' doesn't work if user is not looking at the tab.
|
||||||
|
noLoop();
|
||||||
|
// --> use custom looper.
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
var myroom = -1;
|
||||||
|
var intro;
|
||||||
|
var ready;
|
||||||
|
//
|
||||||
|
socket.on("connect", async function() {
|
||||||
|
console.log("connected!");
|
||||||
|
|
||||||
|
//
|
||||||
|
silence = (await AudioImport("/audio/_silence.wav")).toDestination();
|
||||||
|
clap = (await AudioImport("/audio/clap01.mp3")).toDestination();
|
||||||
|
|
||||||
|
//TESTING... fixed to room 1.
|
||||||
|
// myroom = 1;
|
||||||
|
|
||||||
|
if (myroom == -1 && selectAll(".roomsel").length == 0) {
|
||||||
|
//initial connection -> ask the room number.
|
||||||
|
|
||||||
|
var roomsel = createDiv();
|
||||||
|
roomsel.class("roomsel");
|
||||||
|
var b = createButton("미리보기 Preview!", 1);
|
||||||
|
var d = createDiv("흐름을 향하여 걷는 Walking towards the Flow");
|
||||||
|
d.class("title");
|
||||||
|
b.mouseClicked(function() {
|
||||||
|
silence.start();
|
||||||
|
//clap.start();
|
||||||
|
orchestra();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
selectAll(".roomsel").forEach(item => {
|
||||||
|
item.remove();
|
||||||
|
// 1 second popup '.intro' div
|
||||||
|
intro = createDiv(
|
||||||
|
"미리보기<br>«흐름을 향하여 걷는»은 온라인 공간에 소리의 행렬을 만드는 사운드 퍼레이드입니다. 누구나 참여할 수 있는 이 퍼레이드는 여러분이 보내주시는 소리가 모여 만들어집니다.<br>소리가 들리지 않는다면, 볼륨을 확인해주시고, 스마트폰 환경에서는 진동해제해주세요. <br><br>Preview<br>«Walking Toward the Flow» is a sound parade that creates a procession of sounds in the online space. Anyone can participate. This parade is made by collecting the sounds you sent.<br>If there is no sound, check the volume and turn off the vibration in the smartphone environment."
|
||||||
|
);
|
||||||
|
intro.class("notice intro"); //-> fadeout & disapear by css animation style.
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
roomsel.child(d);
|
||||||
|
roomsel.child(b);
|
||||||
|
} else {
|
||||||
|
//re-connection -> just connect to remembered room!
|
||||||
|
socket.emit("room", myroom, function(res) {
|
||||||
|
if (res) {
|
||||||
|
console.log("entered the room -> " + myroom);
|
||||||
|
} else {
|
||||||
|
console.log("rejected!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//var fading_factor = 0.3; //30%
|
||||||
|
var fading_factor = 0.5; //50%
|
||||||
|
socket.on("post", async function(post) {
|
||||||
|
|
||||||
|
console.log(post);
|
||||||
|
var list = await new Promise((resolve, reject) => {
|
||||||
|
loadJSON("/entries", (json) => resolve(json));
|
||||||
|
})
|
||||||
|
console.log(list);
|
||||||
|
|
||||||
|
// var object = post.object;
|
||||||
|
var object = {
|
||||||
|
"id": 1,
|
||||||
|
"type": "abc",
|
||||||
|
"src": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/pixels.png",
|
||||||
|
"audio": "https://p.dianaband.info/public/sound-parade/" + list[post] + "/audio.mp3",
|
||||||
|
"alt": "알트",
|
||||||
|
"size": {
|
||||||
|
"base": 40,
|
||||||
|
"random": 20
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"base": 20,
|
||||||
|
"random": 10
|
||||||
|
},
|
||||||
|
"showtime": 20000
|
||||||
|
};
|
||||||
|
console.log(object);
|
||||||
|
|
||||||
|
var img = createImg(object.src, object.alt, "", async function(im) {
|
||||||
|
//로딩이 끝나면, start!
|
||||||
|
var pv = new Tone.PanVol(0, -99).toDestination();
|
||||||
|
var snd = await AudioImport(object.audio); // NOTE: url with spaces didn't work here.
|
||||||
|
snd.connect(pv).start();
|
||||||
|
snd.loop = true;
|
||||||
|
|
||||||
|
//로딩이 끝나면, show!
|
||||||
|
im.show();
|
||||||
|
|
||||||
|
//그림의 크기와 초기 위치 ==> 가로 보기인 경우
|
||||||
|
var width = 0;
|
||||||
|
if (windowWidth > windowHeight) {
|
||||||
|
|
||||||
|
width = (windowHeight * (object.size.base * 1.4 + object.size.random * Math.random())) / 100; // 좀더 크게 + 40% (ratio)
|
||||||
|
im.size(width, AUTO);
|
||||||
|
|
||||||
|
im.position(
|
||||||
|
windowWidth * (1 + fading_factor),
|
||||||
|
(windowHeight * (object.y.base + object.y.random * Math.random()) * 0.5) / 100 // 좀더 위로 위로 - 50% (ratio)
|
||||||
|
);
|
||||||
|
|
||||||
|
//그림의 크기와 초기 위치 ==> 세로 보기인 경우
|
||||||
|
} else {
|
||||||
|
|
||||||
|
width = (windowHeight * (object.size.base + object.size.random * Math.random())) / 100; // json에서 정한 크기 그대로. (ratio)
|
||||||
|
im.size(width, AUTO);
|
||||||
|
|
||||||
|
im.position(
|
||||||
|
windowWidth * (1 + fading_factor),
|
||||||
|
(windowHeight * (object.y.base + object.y.random * Math.random())) / 100 // json에서 정한 위치 그대로. (ratio)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//추가 정보들
|
||||||
|
im.attribute("data-type", object.type);
|
||||||
|
im.attribute("data-showtime", object.showtime / 1000); //milli-sec. -> seconds.
|
||||||
|
|
||||||
|
//'아이콘' 들은 애니메이션을 시켜줘야 함...
|
||||||
|
if (object.type == "icon") {
|
||||||
|
//
|
||||||
|
im.class("rotate");
|
||||||
|
im.style("animation-duration", object.rotate + "s");
|
||||||
|
var orgs = im.style("transform-origin").split(" ");
|
||||||
|
var str = parseFloat(orgs[0]) + object.pivot.x + "px";
|
||||||
|
str = str + " " + parseFloat(orgs[1]) + object.pivot.y + "px";
|
||||||
|
im.style("transform-origin", str);
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
//로딩이 다 되면, rendering array에 추가.
|
||||||
|
var bundle = {
|
||||||
|
ref: object,
|
||||||
|
img: im,
|
||||||
|
sound: snd,
|
||||||
|
panvol: pv,
|
||||||
|
width: width
|
||||||
|
};
|
||||||
|
arr.push(bundle);
|
||||||
|
});
|
||||||
|
|
||||||
|
//첨에는 hide
|
||||||
|
img.hide();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
//p5 'draw()' doesn't work if user is not looking at the tab.
|
||||||
|
Tone.Transport.scheduleRepeat((time) => {
|
||||||
|
|
||||||
|
//
|
||||||
|
for (var i = arr.length - 1; i >= 0; i -= 1) {
|
||||||
|
var bundle = arr[i];
|
||||||
|
var img = bundle.img;
|
||||||
|
var showtime = parseFloat(img.attribute("data-showtime"));
|
||||||
|
var type = img.attribute("data-type");
|
||||||
|
var x = img.position().x;
|
||||||
|
var y = img.position().y;
|
||||||
|
y = y + random(-1, 1);
|
||||||
|
x = x - windowWidth / (fr * showtime);
|
||||||
|
|
||||||
|
//
|
||||||
|
if (type == "icon") {
|
||||||
|
img.style("z-index", "-1");
|
||||||
|
}
|
||||||
|
3;
|
||||||
|
|
||||||
|
img.position(x, y);
|
||||||
|
var pan = (x / windowWidth) * 2 - 1;
|
||||||
|
|
||||||
|
//panning
|
||||||
|
var snd = bundle.sound;
|
||||||
|
var pv = bundle.panvol;
|
||||||
|
if (x >= -bundle.width && x < windowWidth) {
|
||||||
|
pan = ((x + bundle.width) / (windowWidth + bundle.width)) * 2 - 1;
|
||||||
|
pv.pan.value = pan;
|
||||||
|
pv.volume.value = 0;//(dB)
|
||||||
|
} else {
|
||||||
|
var range;
|
||||||
|
var knob;
|
||||||
|
if (x >= windowWidth) {
|
||||||
|
range = windowWidth * fading_factor
|
||||||
|
knob = x - windowWidth;
|
||||||
|
pv.pan.value = 1;
|
||||||
|
pv.volume.value = knob / range * -20;
|
||||||
|
} else if (x < -bundle.width) {
|
||||||
|
range = windowWidth * fading_factor
|
||||||
|
knob = (x + bundle.width) * -1;
|
||||||
|
pv.pan.value = -1;
|
||||||
|
pv.volume.value = knob / range * -20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove with sound fade-out
|
||||||
|
var exit_x = -bundle.width - windowWidth * fading_factor;
|
||||||
|
if (x < exit_x) {
|
||||||
|
img.remove();
|
||||||
|
snd.stop();
|
||||||
|
delete snd;
|
||||||
|
delete pv;
|
||||||
|
arr.splice(i, 1);
|
||||||
|
if (arr.length == 0 && playing == false) {
|
||||||
|
setTimeout(() => {
|
||||||
|
createDiv("미리보기가 끝났습니다. <br>Preview is over.").class("notice").style('text-align', 'center');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
|
||||||
|
}, 1.0/fr);
|
||||||
|
Tone.Transport.start()
|
||||||
|
|
||||||
|
// function randomvoiceplay() {
|
||||||
|
// (looper = function(timeout) {
|
||||||
|
// setTimeout(function() {
|
||||||
|
// voice[int(random(19))].play();
|
||||||
|
// looper(random(8000, 12000));
|
||||||
|
// }, timeout);
|
||||||
|
// })(8000);
|
||||||
|
// }
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Loading…
Reference in a new issue