/* TAIMATSU homepage store map (WORLDWIDE section). Loaded site-wide so it also starts after Barba page transitions; it does nothing on pages without #sm-stores. Markup and styles live in the Home page embed. */ (function () { var CDN = "https://cdn.prod.website-files.com/68edcfe95180e579dd4518d4/"; var P = { kap: CDN + "68edcfe95180e579dd451a97_Store_kap.jpg", asa: CDN + "68edcfe95180e579dd451a95_Store_asa.jpg", min: CDN + "68edcfe95180e579dd451a99_Store_min.jpg", kyo: CDN + "68edcfe95180e579dd451a96_Store_kyo.jpg", tsu: CDN + "68edcfe95180e579dd451a98_Store_tsu.jpg", nar: CDN + "68edcfe95180e579dd451ad9_Store_Nar.jpg", shi: CDN + "68edcfe95180e579dd451ae6_Store_Shi.jpg", expKyo: CDN + "68edcfe95180e579dd451ae8_Store_fuji-kyoto.jpg", kiy: CDN + "68edcfe95180e579dd451b14_Store_Kiy.jpg", expAsa: CDN + "68edcfe95180e579dd451b18_Store_fujiasa.jpg", ekimae: CDN + "69362b361c78d0122c299e40_Store_ekimae.jpg", hondori: CDN + "69362bb7743acb37aa80d763_Store_hondori.jpg", omote: CDN + "69362bc331ae3273857e0f52_Stores_omote.jpg", kiyz: CDN + "69366d127b839be8f112f544_Stores_kiyomizuzaka.jpg", red: CDN + "6adf28583e0f08744fb4b833_storemap-musashi-paris-red.jpg", blue: CDN + "6adf2858da6993eae24ae04d_storemap-musashi-paris-blue.jpg", white: CDN + "6adf285889a041f743582502_storemap-musashi-paris-white.jpg", kanazawa: CDN + "6adf28581b55211d73077def_storemap-musashi-kanazawa.jpg", osaka: CDN + "6adf2858d7f554f42617b0c3_storemap-musashi-namba.jpg", shibCenter: CDN + "6adf285989a041f743582518_storemap-musashi-shibuya-center.jpg", shibuya: CDN + "68edcfe95180e579dd451b2b_Store_shibuya.jpg", yokaiSanjo: CDN + "6adf28598732afcaa5a12ff4_storemap-yokai-sanjo.jpg", yokaiAsakusa: CDN + "6adf2859d47632875e45539b_storemap-yokai-asakusa.jpg", yokaiIchinenzaka: CDN + "6adf285989a041f743582564_storemap-yokai-ichinenzaka.jpg", feGion: CDN + "6adf285402959e200a95feeb_storemap-fe-gion.jpg", feNamba: CDN + "6adf285802959e200a960119_storemap-fe-namba.jpg", feHarajuku: CDN + "6adf2857712c05163f89f451_storemap-fe-harajuku.jpg", ittoKanazawa: CDN + "6ae01f651c9c9a2fe5b196dd_storemap-itto-kanazawa.jpg", ittoHiroshima: CDN + "6ae01f6674c0608e936f4109_storemap-itto-hiroshima.jpg", musashiHawaii: CDN + "6ae05943d2a417be2515defa_storemap-musashi-hawaii.jpg" }; var G = "https://maps.app.goo.gl/"; var REGIONS = { world: {pins: {japan: [0.4797, 0.4536], paris: [0.1505, 0.2916], hawaii: [0.6554, 0.6471]}}, japan: {pins: {tokyo: [0.5832, 0.5803], kyoto: [0.4627, 0.602], osaka: [0.4505, 0.6237], nara: [0.4722, 0.6241], kanazawa: [0.4897, 0.5453], hiroshima: [0.362, 0.6328], tsushima: [0.2655, 0.6404]}}, france: {pins: {paris: [0.4936, 0.3283]}}, hawaii: {pins: {hawaii: [0.4695, 0.3643]}} }; var COUNTRIES = [["France", ["paris"]], ["Japan", ["tokyo", "kyoto", "osaka", "nara", "kanazawa", "hiroshima", "tsushima"]], ["USA", ["hawaii"]]]; var CITIES = { tokyo: {name: "Tokyo", heading: "Tokyo Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Kita Kappabashi", P.kap, G + "Vk5Ka3oEVVrDxpzU6"], ["Minami Kappabashi", P.min, G + "MvVgYLsyHr7U91M88"], ["Asakusa", P.asa, G + "feKZcWByPzWGCmYF7"], ["Shibuya", P.shibuya, G + "B3NXMf8BdkaPmfq99"], ["Shibuya Center Street", P.shibCenter, G + "KLTxLnu8C8ZZdemY8"], ["Omotesando", P.omote, G + "nkGEuxHnMMCxoiSo6"]]], ["Yokai Japan", [["Asakusa", P.yokaiAsakusa, G + "qAHQrnDodB7Wh8G87"]]], ["Musashi EXP", [["Kappabashi", P.kap, G + "wcfLAXBKUUXSBVdd9"], ["Asakusa", P.expAsa, G + "f6r8Dpu88vP6gbxe7"]]], ["FE", [["Harajuku Takeshita", P.feHarajuku, G + "Ayw5Vgc2MawDsstw7"], ["Harajuku - Coming Soon"], ["Shibuya Center-gai - Coming Soon"]]]]}, kyoto: {name: "Kyoto", heading: "Kyoto Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Sanjo", P.kyo, G + "oDHoCR1MeJyz2oxh8"], ["Shijo", P.shi, G + "4RpVFtwZTXArZ6iL9"], ["Kawaramachi Eki Mae", P.ekimae, G + "ubTbrj43i3xEoYVKA"], ["Kiyomizu", P.kiy, G + "k7ouMf8bpRcHJMsu6"], ["Kiyomizuzaka", P.kiyz, G + "xy1bQJubAJ1E4QX77"]]], ["Yokai Japan", [["Ichinenzaka", P.yokaiIchinenzaka, "https://maps.google.com/?cid=1129109054342507459"], ["Sanjo", P.yokaiSanjo, G + "oDHoCR1MeJyz2oxh8"]]], ["Musashi EXP", [["Sanjo", P.expKyo, G + "oDHoCR1MeJyz2oxh8"]]], ["FE", [["Gion", P.feGion, G + "PMFjf2QkaD2T7ovg7"]]]]}, osaka: {name: "Osaka", heading: "Osaka Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Namba", P.osaka, G + "iSbEH7gv39ifBcjg6"]]], ["FE", [["Namba", P.feNamba, "https://www.google.com/maps/search/?api=1&query=34.6676795,135.5012203"]]]]}, nara: {name: "Nara", heading: "Nara Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Nara", P.nar, G + "Dmq2zGBmHHXGUuKC6"]]], ["Musashi EXP", [["Nara", P.nar, G + "5WEo6gFLaZpkxWfk9"]]]]}, kanazawa: {name: "Kanazawa", heading: "Kanazawa Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Higashi Chaya", P.kanazawa, G + "RDVDmRSFgjSf5fh57"]]], ["ITTO", [["Higashi Chaya", P.ittoKanazawa, G + "ueGf6YTe8Pgs8UZV8"]]]]}, hiroshima: {name: "Hiroshima", heading: "Hiroshima Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Hondori", P.hondori, G + "fouE1bJ48mpmyQjG6"]]], ["ITTO", [["Hondori", P.ittoHiroshima, G + "TGzNPqF1CeLVzT2PA"]]]]}, tsushima: {name: "Tsushima", heading: "Tsushima Japan", region: "japan", world: "japan", brands: [ ["Musashi Japan", [["Izuhara", P.tsu, G + "KA2QaR7vEzzoqGBy6"]]]]}, paris: {name: "Paris", heading: "Paris France", region: "france", world: "paris", brands: [ ["Musashi Japan", [["Archives", P.red, G + "5FmYcTVt1nPeyKnR6"], ["Sainte-Croix", P.blue, G + "GnWPQysEoaUsreecA"], ["Temple", P.white, G + "8UbygCL8bkYfrUdM7"]]]]}, hawaii: {name: "Hawaii", heading: "Hawaii USA", region: "hawaii", world: "hawaii", brands: [ ["Musashi Japan", [["Waikiki", P.musashiHawaii, G + "bB4EHfYGohrrYBvu8"]]]]} }; var WORLD_M = {japan: [0.4797, 0.3033], paris: [0.1505, 0.1996], hawaii: [0.6554, 0.427]}; var MATCH = {japan: {a: [0.506, 0.5598], c: 0.12414, t: -0.0249}, france: {a: [0.4936, 0.3283], c: 0.08199, t: -0.6422}, hawaii: {a: [0.4695, 0.3643], c: 0.03309, t: 0.1001}}; var COUNTRY_NAME = {japan: "Japan"}; var CARET = ''; var BACKROW = '
"; function cover(c) { for (var i = 0; i < c.brands.length; i++) for (var j = 0; j < c.brands[i][1].length; j++) if (c.brands[i][1][j][1]) return c.brands[i][1][j][1]; return null; } function esc(s) { return String(s).replace(/&/g, "&").replace(/' + esc(s) + ""; } function colOf(region) { for (var i = 0; i < COUNTRIES.length; i++) if (CITIES[COUNTRIES[i][1][0]].region === region) return i; return 0; } function citiesOf(region) { for (var i = 0; i < COUNTRIES.length; i++) if (CITIES[COUNTRIES[i][1][0]].region === region) return COUNTRIES[i][1]; return []; } function setup(root) { root.dataset.ready = "1"; var gsap = window.gsap, ST = window.ScrollTrigger; var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches; var canHover = window.matchMedia("(hover: hover) and (pointer: fine)").matches; var mobile = window.matchMedia("(max-width:767px)"); var D = reduce ? 0 : 1; var canIntro = !reduce && !!ST; var stage = root.querySelector(".sm-stage"), maps = root.querySelector(".sm-maps"), list = root.querySelector(".sm-list"); var reveal = root.querySelector(".sm-reveal"), coverEl = root.querySelector(".sm-cover"), runEl = root.querySelector(".sm-run"), blend = root.querySelector(".sm-blend"); var front = root.querySelector(".sm-front"), backFace = root.querySelector(".sm-backface"); var frontH = front.querySelector(".sm-h"), backH = backFace.querySelector(".sm-h"); var photos = root.querySelectorAll(".sm-photo img"); var layers = {}; root.querySelectorAll(".sm-layer").forEach(function (el) { layers[el.dataset.region] = el; }); function worldPins() { return mobile.matches ? WORLD_M : REGIONS.world.pins; } function qa(sel) { return Array.prototype.slice.call(list.querySelectorAll(sel)); } var pins = {}; Object.keys(REGIONS).forEach(function (r) { pins[r] = {}; Object.keys(REGIONS[r].pins).forEach(function (k) { var xy = REGIONS[r].pins[k], s; if (r === "world") { s = document.createElement("span"); } else { s = document.createElement("button"); s.type = "button"; s.dataset.city = k; s.setAttribute("aria-label", CITIES[k].name); } s.className = "sm-pin"; s.innerHTML = '' + (r === "world" ? "" : '' + esc(CITIES[k].name) + ""); s.style.left = xy[0] * 100 + "%"; s.style.top = xy[1] * 100 + "%"; layers[r].appendChild(s); pins[r][k] = s; }); }); function placeWorldPins() { var wp = worldPins(); Object.keys(pins.world).forEach(function (k) { pins.world[k].style.left = wp[k][0] * 100 + "%"; pins.world[k].style.top = wp[k][1] * 100 + "%"; }); } placeWorldPins(); function pops(r) { return Object.keys(pins[r]).map(function (k) { return pins[r][k].firstChild; }); } gsap.set(layers.world, {transformOrigin: "0 0", x: 0, y: 0, scale: 1}); ["japan", "france", "hawaii"].forEach(function (r) { gsap.set(layers[r], {transformOrigin: "0 0", xPercent: -50, yPercent: -50, x: 0, y: 0, scale: 1}); gsap.set(pops(r), {scale: 0}); }); function fit(h) { h.style.fontSize = ""; var max = stage.clientWidth * 0.94, w = h.scrollWidth; if (w > max) h.style.fontSize = parseFloat(getComputedStyle(h).fontSize) * max / w + "px"; } function pose(p) { front.style.transform = p ? "translateY(" + (-100 * p) + "%) rotateX(" + (90 * p) + "deg)" : ""; backFace.style.transform = "translateY(" + (100 - 100 * p) + "%) rotateX(" + (90 * p - 90) + "deg)"; } var cur = "Worldwide", want = "Worldwide", flipping = false; function heading(text) { want = text; if (!flipping) flip(); } function flip() { if (want === cur) return; var next = want; backH.textContent = next; fit(backH); if (!D) { frontH.textContent = next; fit(frontH); cur = next; return; } flipping = true; var o = {p: 0}; gsap.to(o, {p: 1, duration: 1, ease: "expo.inOut", onUpdate: function () { pose(o.p); }, onComplete: function () { frontH.textContent = next; fit(frontH); pose(0); cur = next; flipping = false; if (want !== cur) flip(); }}); } var shown = null, token = 0, layerZ = 1; function photo(url) { if (!url) return noPhoto(); if (shown && shown.dataset.src === url) { gsap.to(shown, {autoAlpha: 1, duration: 0.3, overwrite: "auto"}); return; } var img = shown === photos[0] ? photos[1] : photos[0], my = ++token, prev = shown; var go = function () { if (my !== token) return; img.style.zIndex = ++layerZ; gsap.killTweensOf(img); if (D) { gsap.fromTo(img, {autoAlpha: 1, clipPath: "inset(100% 0% 0% 0%)", scale: 1.12}, {clipPath: "inset(0% 0% 0% 0%)", scale: 1, duration: 0.9, ease: "expo.out", onComplete: function () { if (prev && prev !== img && shown === img) gsap.set(prev, {autoAlpha: 0}); }}); } else { gsap.set(img, {autoAlpha: 1, clipPath: "none", scale: 1}); if (prev && prev !== img) gsap.set(prev, {autoAlpha: 0}); } shown = img; }; img.dataset.src = url; img.onload = go; img.src = url; if (img.complete && img.naturalWidth) go(); } function noPhoto() { token++; gsap.to(photos, {autoAlpha: 0, duration: D ? 0.3 : 0, overwrite: true}); shown = null; } function preload(urls) { urls.forEach(function (u) { if (u) { var i = new Image(); i.src = u; } }); } function preloadCities(keys) { var all = []; keys.forEach(function (k) { CITIES[k].brands.forEach(function (b) { b[1].forEach(function (s) { all.push(s[1]); }); }); }); preload(all); } function emphasize(region, key) { Object.keys(pins).forEach(function (r) { Object.keys(pins[r]).forEach(function (k) { pins[r][k].classList.toggle("is-on", r === region && k === key); }); }); } function dim(items, active) { items.forEach(function (el) { el.classList.toggle("is-dim", !!active && el !== active); }); } function framed(el, f, extra) { var w = el.offsetWidth, h = el.offsetHeight, s = 1.1, k = 0.3, fx = f[0] * w, fy = f[1] * h; var v = {scale: s, x: fx + k * (w / 2 - fx) - s * fx, y: fy + k * (h / 2 - fy) - s * fy}; for (var key in extra) v[key] = extra[key]; return v; } function regionPose(view, region, key, extra) { if (view === "city") return framed(layers[region], REGIONS[region].pins[key], extra); var v = {scale: 1, x: 0, y: 0}; for (var k in extra) v[k] = extra[k]; return v; } function worldKey(region) { return region === "france" ? "paris" : region; } function shownOpacity(el) { return parseFloat(gsap.getProperty(el, "opacity")) || 0; } var cam = null; function geo(region) { var W = layers.world, R = layers[region], m = MATCH[region], wp = worldPins()[worldKey(region)]; var rw = R.offsetWidth, rh = R.offsetHeight, ww = W.offsetWidth, wh = W.offsetHeight; return {k: ww / 1440 * m.c / (rw / 1000), t: m.t, ax: m.a[0] * rw, ay: m.a[1] * rh, wx: wp[0] * ww, wy: wp[1] * wh, rx: R.offsetLeft - rw / 2, ry: R.offsetTop - rh / 2, bx: W.offsetLeft, by: W.offsetTop}; } function camOf(g, R) { var s = gsap.getProperty(R, "scaleX"), t = Math.tan(gsap.getProperty(R, "skewX") * Math.PI / 180); return {x: g.rx + gsap.getProperty(R, "x") + s * (g.ax + t * g.ay), y: g.ry + gsap.getProperty(R, "y") + s * g.ay, s: s, t: t}; } function camOfWorld(g) { var W = layers.world, s = gsap.getProperty(W, "scaleX"); return {x: g.bx + gsap.getProperty(W, "x") + s * g.wx, y: g.by + gsap.getProperty(W, "y") + s * g.wy, s: s * g.k, t: g.t}; } function camAt(g, p) { return {x: g.rx + p.x + p.scale * g.ax, y: g.ry + p.y + p.scale * g.ay, s: p.scale, t: 0}; } function camRest(g) { return {x: g.bx + g.wx, y: g.by + g.wy, s: g.k, t: g.t}; } function fly(region, g, a, b, into) { if (cam) cam.kill(); var W = layers.world, R = layers[region]; gsap.killTweensOf([W, R]); var put = function (e) { var s = a.s * Math.pow(b.s / a.s, e), t = a.t + (b.t - a.t) * e, x = a.x + (b.x - a.x) * e, y = a.y + (b.y - a.y) * e, sw = s / g.k; var u = Math.min(1, Math.max(0, Math.log(sw) / fade)), v = Math.min(1, Math.max(0, Math.log(sw) / Math.LN2)); gsap.set(R, {x: x - g.rx - s * (g.ax + t * g.ay), y: y - g.ry - s * g.ay, scale: s, skewX: Math.atan(t) * 180 / Math.PI, autoAlpha: v * v * (3 - 2 * v)}); gsap.set(W, {x: x - g.bx - sw * g.wx, y: y - g.by - sw * g.wy, scale: sw, autoAlpha: 1 - u * u * (3 - 2 * u)}); W.style.setProperty("--pk", 1 / sw); }; var fade = Math.log(Math.max(3.5, Math.pow(1.1 / g.k, 0.6))); var o = {e: 0}; put(0); cam = gsap.to(o, {e: 1, duration: D * 1.4, ease: "expo.inOut", onUpdate: function () { put(o.e); }, onComplete: function () { cam = null; if (!into) { gsap.set(W, {x: 0, y: 0, scale: 1}); W.style.removeProperty("--pk"); } }}); } function popPins(region, delay) { gsap.fromTo(pops(region), {scale: 0}, {scale: 1, duration: D ? 0.7 : 0, ease: "back.out(3)", stagger: D ? 0.07 : 0, delay: delay, overwrite: true}); } var state = {view: "world", city: null, region: null}, leaveTimer = null, swapTl = null; function renderWorld() { return COUNTRIES.map(function (c, i) { return '
" + c[1].map(function (k) { return '"; }).join("") + "
"; }).join(""); } function renderCountry(region) { return BACKROW + '
' + citiesOf(region).map(function (k) { return '"; }).join("") + "
"; } function renderRows(c) { var out = []; c.brands.forEach(function (b, bi) { b[1].forEach(function (s, si) { var ph = s[1] ? ' data-photo="' + esc(s[1]) + '"' : ""; var item = s[2] ? '" + txt(s[0]) + "" : '" + txt(s[0]) + ""; out.push('
' + (si === 0 ? txt(b[0]) : "") + "" + item + "
"); }); }); return out.join(""); } function renderCity(key) { return BACKROW + '
' + renderRows(CITIES[key]) + "
"; } function reserve() { var probe = document.createElement("div"); probe.className = "sm-list"; probe.setAttribute("aria-hidden", "true"); probe.style.cssText = "position:absolute;left:0;top:0;width:" + list.offsetWidth + "px;visibility:hidden;pointer-events:none;margin:0"; reveal.appendChild(probe); var max = 0; [renderWorld(), renderCountry("japan")].concat(Object.keys(CITIES).map(renderCity)).forEach(function (html, i) { probe.classList.toggle("is-sub", i > 0); probe.innerHTML = html; max = Math.max(max, probe.offsetHeight); }); reveal.removeChild(probe); list.style.minHeight = Math.ceil(max) + "px"; } function setSub(on) { root.classList.toggle("is-sub", on); list.classList.toggle("is-sub", on); } function swap(scope, apply, after) { if (swapTl) swapTl.kill(); var tl = swapTl = gsap.timeline(); if (D) { tl.to(scope.querySelectorAll(".sm-t"), {yPercent: -110, duration: 0.45, ease: "power3.in", stagger: 0.012, overwrite: "auto"}, 0); var oldBack = apply.full ? scope.querySelectorAll(".sm-back") : []; if (oldBack.length) tl.to(oldBack, {autoAlpha: 0, scale: 0.5, duration: 0.35, ease: "power3.in", overwrite: "auto"}, 0); } tl.add(function () { apply(); if (D) { gsap.set(list.querySelectorAll(apply.full ? ".sm-t" : ".sm-rows .sm-t"), {yPercent: 110}); var nb = apply.full ? list.querySelectorAll(".sm-back") : []; if (nb.length) gsap.set(nb, {autoAlpha: 0, scale: 0.5}); } }); tl.add(function () { if (D) { gsap.to(list.querySelectorAll(apply.full ? ".sm-t" : ".sm-rows .sm-t"), {yPercent: 0, duration: 1, ease: "expo.out", stagger: 0.022, overwrite: "auto"}); var nb2 = apply.full ? list.querySelectorAll(".sm-back") : []; if (nb2.length) gsap.to(nb2, {autoAlpha: 1, scale: 1, duration: 0.9, ease: "expo.out", overwrite: "auto"}); } if (after) gsap.delayedCall(D ? 0.08 : 0, after); }, D ? "+=0.12" : ">"); } function resetWorld() { noPhoto(); emphasize(null, null); } function keyboardFocus() { var a = document.activeElement; return !!a && list.contains(a) && a.matches(":focus-visible"); } function enter(view, key) { if (state.view !== "world") return; var region = view === "city" ? CITIES[key].region : key; var R = layers[region], kb = keyboardFocus(); clearTimeout(leaveTimer); state = {view: view, city: view === "city" ? key : null, region: region}; heading(view === "city" ? CITIES[key].heading : COUNTRY_NAME[region]); noPhoto(); preloadCities(view === "city" ? [key] : citiesOf(region)); Object.keys(layers).forEach(function (r) { if (r !== "world" && r !== region) gsap.to(layers[r], {autoAlpha: 0, duration: D * 0.3, overwrite: true}); }); var g = geo(region), seen = shownOpacity(R) > 0; if (!seen) gsap.set(pops(region), {scale: 0}); fly(region, g, seen ? camOf(g, R) : camOfWorld(g), camAt(g, regionPose(view, region, key)), true); popPins(region, D * 0.95); emphasize(region, view === "city" ? key : null); var apply = function () { setSub(true); list.innerHTML = view === "city" ? renderCity(key) : renderCountry(region); bind(); }; apply.full = true; swap(list, apply, function () { if (kb) { var b = list.querySelector(".sm-back"); if (b) b.focus(); } }); } function toCity(key) { if (state.view === "world" || key === state.city || CITIES[key].region !== state.region) return; var c = CITIES[key], R = layers[c.region], full = state.view === "country", kb = keyboardFocus(); clearTimeout(leaveTimer); state = {view: "city", city: key, region: c.region}; heading(c.heading); noPhoto(); hoverPin(null); preloadCities([key]); if (cam) { cam.kill(); cam = null; gsap.to(layers.world, {autoAlpha: 0, duration: D * 0.3}); gsap.to(R, {autoAlpha: 1, duration: D * 0.3}); } gsap.to(R, framed(R, REGIONS[c.region].pins[key], {skewX: 0, duration: D * 1.3, ease: "expo.inOut", overwrite: "auto"})); emphasize(c.region, key); if (full) { var apply = function () { list.innerHTML = renderCity(key); bind(); }; apply.full = true; swap(list, apply, function () { if (kb) { var b = list.querySelector(".sm-back"); if (b) b.focus(); } }); } else { var box = list.querySelector(".sm-rows"); var apply2 = function () { box.innerHTML = renderRows(c); bindRows(); }; swap(box, apply2); } } function openWorld() { if (state.view === "world") return; var region = state.region, R = layers[region], kb = keyboardFocus(); var back = state.city ? '[data-city="' + state.city + '"]' : '.sm-country[data-col="' + colOf(region) + '"]'; clearTimeout(leaveTimer); state = {view: "world", city: null, region: null}; noPhoto(); hoverPin(null); var g = geo(region); fly(region, g, camOf(g, R), camRest(g), false); heading("Worldwide"); emphasize(null, null); var apply = function () { setSub(false); list.innerHTML = renderWorld(); bind(); }; apply.full = true; swap(list, apply, function () { if (kb) { var b = list.querySelector(back) || list.querySelector(".sm-country"); if (b) b.focus(); } }); } var hovered = null, hoverFrom = null; function hoverPin(btn, from) { hoverFrom = btn ? from : null; if (hovered === btn) return; if (hovered) { hovered.classList.remove("is-hover"); hovered.parentNode.style.cursor = ""; } hovered = btn; if (btn) { btn.classList.add("is-hover"); btn.parentNode.style.cursor = btn.classList.contains("is-on") ? "" : "pointer"; } } function nearestPin(r, x, y, radius) { var best = null, bd = radius; Object.keys(pins[r]).forEach(function (k) { var b = pins[r][k].getBoundingClientRect(), d = Math.hypot(b.left + b.width / 2 - x, b.top + b.height / 2 - y); if (d < bd) { bd = d; best = pins[r][k]; } }); return best; } ["japan", "france", "hawaii"].forEach(function (r) { var L = layers[r]; if (canHover) { L.addEventListener("mousemove", function (e) { hoverPin(state.view !== "world" ? nearestPin(r, e.clientX, e.clientY, 36) : null, "map"); }); L.addEventListener("mouseleave", function () { hoverPin(null); }); } L.addEventListener("click", function (e) { if (state.view === "world") return; var own = e.target.closest ? e.target.closest(".sm-pin") : null; var btn = e.detail === 0 && own ? own : nearestPin(r, e.clientX, e.clientY, 44); if (btn && btn.dataset.city) toCity(btn.dataset.city); }); }); function bindRows() { var items = qa(".sm-rows .sm-item"), tapped = null; items.forEach(function (el) { var on = function () { clearTimeout(leaveTimer); dim(items, el); photo(el.dataset.photo || null); }; if (canHover) { el.addEventListener("mouseenter", on); el.addEventListener("focus", on); } else { el.addEventListener("click", function (e) { if (tapped !== el) { e.preventDefault(); tapped = el; on(); } }); } }); } function bind() { var back = list.querySelector(".sm-back"); if (back) back.addEventListener("click", openWorld); if (state.view === "world") { var items = qa(".sm-item"), caps = qa(".sm-country"), all = items.concat(caps); items.forEach(function (el) { var key = el.dataset.city; el.addEventListener("click", function () { enter("city", key); }); if (canHover) { var on = function () { clearTimeout(leaveTimer); dim(caps, null); dim(items, el); photo(cover(CITIES[key])); emphasize("world", CITIES[key].world); }; el.addEventListener("mouseenter", on); el.addEventListener("focus", on); } }); caps.forEach(function (el) { var keys = COUNTRIES[+el.dataset.col][1]; el.addEventListener("click", function () { if (keys.length === 1) enter("city", keys[0]); else enter("country", CITIES[keys[0]].region); }); if (canHover) { var on = function () { clearTimeout(leaveTimer); all.forEach(function (x) { x.classList.toggle("is-dim", x.parentNode !== el.parentNode); }); photo(cover(CITIES[keys[0]])); emphasize("world", CITIES[keys[0]].world); }; el.addEventListener("mouseenter", on); el.addEventListener("focus", on); } }); } else if (state.view === "country") { var cities = qa(".sm-cities .sm-item"); cities.forEach(function (el) { var key = el.dataset.city; el.addEventListener("click", function () { toCity(key); }); if (canHover) { var on = function () { clearTimeout(leaveTimer); dim(cities, el); photo(cover(CITIES[key])); hoverPin(pins[state.region][key], "list"); }; el.addEventListener("mouseenter", on); el.addEventListener("focus", on); } }); } else { bindRows(); } } function release() { dim(qa(".sm-item, .sm-country"), null); if (state.view === "world") resetWorld(); else { noPhoto(); if (hoverFrom === "list") hoverPin(null); } } list.addEventListener("mouseleave", function () { if (!canHover) return; clearTimeout(leaveTimer); leaveTimer = setTimeout(release, 180); }); list.addEventListener("focusout", function (e) { if (list.contains(e.relatedTarget)) return; release(); }); var intro = null; function buildIntro() { if (intro) { intro.st.kill(); intro.tl.kill(); intro = null; } if (!canIntro) return; var vh = window.innerHeight; var O = Math.max(0, -parseFloat(getComputedStyle(root).marginTop) || 0); var s0 = Math.max(0, O - (mobile.matches ? -0.05 : 0.25) * vh), s1 = s0 + 0.75 * vh, g = 0.1 * vh; var h0 = s1 + 0.14 * vh, h1 = h0 + 0.3 * vh, l0 = h1 - 0.06 * vh, l1 = l0 + 0.16 * vh, run = l1 + 0.22 * vh; runEl.style.height = run + "px"; var wl = layers.world, wp = worldPins().japan; var mx = wl.offsetLeft + wp[0] * wl.offsetWidth, my = wl.offsetTop + wp[1] * wl.offsetHeight; var cx = maps.offsetLeft + mx, cy = maps.offsetTop + my; var W = stage.offsetWidth, H = Math.max(stage.offsetHeight, vh); var sx = mobile.matches ? W / 2 : cx; var R0 = Math.ceil(Math.max(Math.hypot(sx, cy), Math.hypot(W - sx, cy), Math.hypot(sx, H - cy), Math.hypot(W - sx, H - cy))) + 8; var order = ["japan", "paris", "hawaii"].map(function (k) { return pins.world[k].firstChild; }); var hp = {p: 0}; var tl = gsap.timeline({paused: true}); tl.set({}, {}, run); tl.fromTo(coverEl, {autoAlpha: 1, backgroundColor: "#ffffff", clipPath: "circle(" + R0 + "px at " + sx + "px " + cy + "px)"}, {clipPath: "circle(18px at " + sx + "px " + cy + "px)", duration: s1 - g - s0, ease: "none"}, s0); tl.to(coverEl, {clipPath: "circle(5px at " + cx + "px " + cy + "px)", duration: g, ease: "power2.inOut"}, s1 - g); tl.to(coverEl, {backgroundColor: "#e8741f", duration: 0.09 * vh, ease: "none"}, s1 - 0.09 * vh); tl.set(coverEl, {autoAlpha: 0}, s1 + 0.01 * vh); tl.fromTo(maps, {opacity: 0.3, scale: 1.12, transformOrigin: mx + "px " + my + "px"}, {opacity: 1, scale: 1, duration: s1 - s0, ease: "power2.out"}, s0); gsap.set(order, {scale: 0}); order.forEach(function (el, i) { tl.fromTo(el, {scale: 0}, {scale: 1, duration: 0.07 * vh, ease: "back.out(3)", immediateRender: false}, s1 - 0.03 * vh + i * 0.05 * vh); }); tl.fromTo(blend, {autoAlpha: 0, y: 50}, {autoAlpha: 1, y: 0, duration: h1 - h0, ease: "none"}, h0); tl.fromTo(hp, {p: 0}, {p: 1, duration: h1 - h0, ease: "none", onUpdate: function () { if (!flipping && state.view === "world" && cur === "Worldwide") pose(hp.p >= 1 ? 0 : hp.p); }}, h0); tl.fromTo(reveal, {autoAlpha: 0, y: 30}, {autoAlpha: 1, y: 0, duration: l1 - l0, ease: "power2.out"}, l0); var liveAt = l0 + 0.5 * (l1 - l0); var st = ST.create({trigger: root, start: "top top", end: "+=" + run, scrub: 0.6, animation: tl, onUpdate: function (self) { var live = self.progress * run >= liveAt; root.classList.toggle("is-live", live); if (!live && state.view !== "world") openWorld(); }}); intro = {st: st, tl: tl}; root.classList.toggle("is-live", st.progress * run >= liveAt); } list.innerHTML = renderWorld(); bind(); pose(0); fit(frontH); reserve(); if (canIntro) { root.classList.add("sm-js"); buildIntro(); ST.refresh(); } else { root.classList.add("is-live"); } var resizeT = null, lastW = window.innerWidth, lastH = window.innerHeight; window.__smFit = function () { if (!document.body.contains(root)) return; fit(frontH); clearTimeout(resizeT); resizeT = setTimeout(function () { var w = window.innerWidth, h = window.innerHeight; if (w === lastW && Math.abs(h - lastH) < 150) return; lastW = w; lastH = h; placeWorldPins(); reserve(); if (cam) cam.progress(1); if (state.view !== "world") gsap.set(layers[state.region], regionPose(state.view, state.region, state.city, {skewX: 0})); if (canIntro) { buildIntro(); ST.refresh(); } }, 250); }; if (document.fonts && document.fonts.ready) document.fonts.ready.then(function () { if (!flipping) fit(frontH); reserve(); }); var covers = []; Object.keys(CITIES).forEach(function (k) { covers.push(cover(CITIES[k])); }); setTimeout(function () { preload(covers); }, 1500); } function boot() { var root = document.getElementById("sm-stores"); if (!root || root.dataset.ready) return true; if (!window.gsap) return false; setup(root); return true; } function start() { if (!window.__smHooked && window.barba && window.barba.hooks) { window.__smHooked = true; window.barba.hooks.after(function () { setTimeout(start, 150); }); } if (boot()) return; var n = 0, t = setInterval(function () { if (boot() || ++n > 100) clearInterval(t); }, 100); } if (!window.__smResize) { window.__smResize = true; window.addEventListener("resize", function () { if (window.__smFit) window.__smFit(); }); } if (document.readyState !== "loading") start(); else document.addEventListener("DOMContentLoaded", start); })();