<!DOCTYPE html>
<html lang="th">
<head>
<!-- Playables SDK -->
<script>// Playables SDK v1.0.0
// Game lifecycle bridge: rAF-based game-ready detection + event communication
(function() {
'use strict';
// Idempotency: skip if already initialized (e.g., server-side
injection
// followed by client-side inject-javascript via the Bloks webview
component).
if (window.playablesSDK) return;
var HANDLER_NAME = 'playablesGameEventHandler';
var ANDROID_BRIDGE_NAME = '_MetaPlayablesBridge';
var RAF_FRAME_THRESHOLD = 3;
var gameReadySent = false;
var firstInteractionSent = false;
var errorSent = false;
var frameCount = 0;
var originalRAF = window.requestAnimationFrame;
// --- Transport Layer ---
function hasIOSBridge() {
return !!(window.webkit &&
window.webkit.messageHandlers
&&
window.webkit.messageHandlers[HANDLER_NAME]);
}
function hasAndroidBridge() {
return !!(window[ANDROID_BRIDGE_NAME] &&
typeof
window[ANDROID_BRIDGE_NAME].postEvent === 'function');
}
function isInIframe() {
return !!(window.parent && window.parent !== window);
}
function sendEvent(eventName, payload) {
var message = {
type: eventName,
payload: payload || {},
timestamp: Date.now()
};
if (hasIOSBridge()) {
try {
window.webkit.messageHandlers[HANDLER_NAME].postMessage(message);
} catch (e) { /* ignore */ }
return;
}
if (hasAndroidBridge()) {
try {
var p = payload || {};
p.__secureToken = window.__fbAndroidBridgeAuthToken ||
'';
p.timestamp = message.timestamp;
window[ANDROID_BRIDGE_NAME].postEvent(
eventName,
JSON.stringify(p)
);
} catch (e) { /* ignore */ }
return;
}
if (isInIframe()) {
try {
window.parent.postMessage(message, '*');
} catch (e) { /* ignore */ }
return;
}
}
// --- rAF Game-Ready Detection ---
function onFrame() {
if (gameReadySent) return;
frameCount++;
if (frameCount >= RAF_FRAME_THRESHOLD) {
gameReadySent = true;
sendEvent('game_ready', {
frame_count: frameCount,
detected_at: Date.now()
});
return;
}
originalRAF.call(window, onFrame);
}
if (originalRAF) {
window.requestAnimationFrame = function(callback) {
if (!gameReadySent) {
return originalRAF.call(window,
function(timestamp) {
frameCount++;
if (frameCount >= RAF_FRAME_THRESHOLD
&& !gameReadySent) {
gameReadySent = true;
sendEvent('game_ready', {
frame_count: frameCount,
detected_at: Date.now()
});
}
callback(timestamp);
});
}
return originalRAF.call(window, callback);
};
}
// --- First User Interaction Detection ---
function setupFirstInteractionDetection() {
var events = ['touchstart', 'mousedown', 'keydown'];
function onFirstInteraction() {
if (firstInteractionSent) return;
firstInteractionSent = true;
sendEvent('user_interaction_start', null);
for (var i = 0; i < events.length; i++) {
document.removeEventListener(events[i],
onFirstInteraction, true);
}
}
for (var i = 0; i < events.length; i++) {
document.addEventListener(events[i], onFirstInteraction,
true);
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded',
setupFirstInteractionDetection);
} else {
setupFirstInteractionDetection();
}
// --- Auto Error Capture ---
window.addEventListener('error', function(event) {
if (errorSent) return;
errorSent = true;
sendEvent('error', {
message: event.message || 'Unknown error',
source: event.filename || '',
lineno: event.lineno || 0,
colno: event.colno || 0,
auto_captured: true
});
});
window.addEventListener('unhandledrejection', function(event) {
if (errorSent) return;
errorSent = true;
var reason = event.reason;
sendEvent('error', {
message: (reason instanceof Error) ? reason.message :
String(reason),
type: 'unhandled_promise_rejection',
auto_captured: true
});
});
// --- Public API ---
window.playablesSDK = {
complete: function(score) {
sendEvent('game_ended', {
score: score,
completed: true
});
},
error: function(message) {
if (errorSent) return;
errorSent = true;
sendEvent('error', {
message: message || 'Unknown error',
auto_captured: false
});
},
sendEvent: function(eventName, payload) {
if (!eventName || typeof eventName !== 'string') return;
sendEvent(eventName, payload);
}
};
// Kick off rAF detection in case no game code calls rAF immediately
if (originalRAF) {
originalRAF.call(window, onFrame);
}
})();</script>
<!-- PLAYABLE_TOUCH_PATCH_V1 --><script>
(function() {
if (window.__playableTouchPatchInstalled) return;
window.__playableTouchPatchInstalled = true;
var origAdd = EventTarget.prototype.addEventListener;
var blockedTypes = { touchstart: 1, touchmove: 1, wheel: 1 };
EventTarget.prototype.addEventListener = function(type, listener,
options) {
if (blockedTypes[type]) {
if (options === undefined || options === null) {
options = { passive: true };
} else if (typeof options === 'boolean') {
options = { capture: options, passive: true };
} else {
options = Object.assign({}, options, { passive:
true });
}
}
return origAdd.call(this, type, listener, options);
};
})();
</script><script>window.Intl=window.Intl||{};Intl.t=function(s){return(Intl._locale&&Intl._locale[s])||s;};</script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>คู่มือทำคอนเทนต์ท่องเที่ยวเชียงใหม่ด้วยมือถือ</title>
<style>
body { font-family: 'Sarabun', system-ui, sans-serif; line-height: 1.8;
max-width: 800px; margin: 40px auto; padding: 0 20px; color: #222; background:
#faf9f7; }
h1 { color: #b45309; border-bottom: 3px solid #f59e0b; padding-bottom: 10px; }
h2 { color: #92400e; margin-top: 40px; }
h3 { color: #78350f; }
blockquote { background: #fffbeb; border-left: 4px solid #f59e0b; padding:
12px 16px; margin: 20px 0; }
</style>
</head>
<body>
<h1>คู่มือทำคอนเทนต์ท่องเที่ยวเชียงใหม่ด้วยมือถือ</h1>
<p><strong>สำหรับครีเอเตอร์ท้องถิ่น ร้านค้า และคนรักเชียงใหม่ |
ฉบับ 30 หน้า</strong></p>
<blockquote>ทำด้วยมือถือเครื่องเดียว ถ่าย เล่า ตัด โพสต์
จบ</blockquote>
<h2>สารบัญ (ย่อ)</h2>
<ul>
<li>บทที่ 1 - วางแผนก่อนออกกอง</li>
<li>บทที่ 2 - เซ็ตมือถือให้พร้อม</li>
<li>บทที่ 3 - ถ่ายภาพและวิดีโอให้น่าหยุดดู</li>
<li>บทที่ 4 - เล่าเรื่องแบบคนเหนือ</li>
<li>บทที่ 5 - ตัดต่อบนมือถือให้ไว</li>
<li>บทที่ 6 - โพสต์ให้ปัง วัดผลให้เป็น</li>
</ul>
<h2>บทที่ 1 - วางแผนก่อนออกกอง</h2>
<p>เชียงใหม่มีร้านกาแฟมากกว่า 2,000 ร้าน วัดเก่า 300 แห่ง และดอยรอบเมือง
แต่คอนเทนต์ที่คนจำได้ไม่ใช่ที่สวยที่สุด
แต่คือเรื่องที่เล่าง่ายที่สุด</p>
<h3>1.1 หาแก่นเรื่อง: 3 มุม</h3>
<p>1) มุมกินแบบคนท้องถิ่น - ข้าวซอย, ก๋วยเตี๋ยวช้างม่อย 2) มุมหลบคน -
แม่กำปองเช้า, แม่ริมหน้าฝน 3) มุมวัฒนธรรมสั้น - ตุง, โคมยี่เป็ง</p>
<h3>1.2 เลือกกลุ่มคนดู</h3>
<p>นักท่องเที่ยวไทย / Digital Nomad / คนเชียงใหม่ เลือก 1
กลุ่มก่อน</p>
<h3>1.3 Content Pillars</h3>
<p>พาไปกิน, พาไปหลบ, พาไปรู้, พาไปทำ - วน 4 เสานี้ 7 วัน</p>
<p><em>ดูไฟล์ Markdown ฉบับเต็มด้านล่างสำหรับเนื้อหาครบทั้ง 6
บท</em></p>
</body>
</html>