UNPKG

spatial-navigation-polyfill

Version:
188 lines (177 loc) 7.25 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="application-name" content="Test Navigation Behavior"> <meta name="author" content="Jeonghee Ahn"> <meta name="description" content="You can directly look into the spatial navigation behavior by yourself using elements you create and arrange. Try to create an element via <b>mouse dragging from empty space</b>, move an element via <b>mouse dragging from inside the element</b>, and delete an element via <b>right click</b>. In order to share a specific arrangement, you can get the snapshot using a set of expressions below as well."> <link rel="stylesheet" href="spatnav-style.css"> <script src="spatnav-utils.js"></script> <script src="../../polyfill/spatial-navigation-polyfill.js"></script> </head> <body onload="init()"> <div id="container"></div> <textarea id="nodeInfo"></textarea> </body> <style> #container { margin-left: 10px; width: 720px; height: 400px; border: 2px #555 solid;; cursor: crosshair; background-size: 40px 40px; background-image: linear-gradient(to right, #777 1px, transparent 1px), linear-gradient(to bottom, #777 1px, transparent 1px); } #nodeInfo { margin-left: 10px; width: 720px; height: 150px; font-family: 'Courier New', Courier, monospace; } .b1 { position: absolute; box-sizing: border-box; cursor: pointer; text-align: center; font-size: 24px; } .b1:focus { background: #3e6e86; outline: 0px solid black; } .temp_node { position: absolute; box-sizing: border-box; border: 1px #777 dashed; } </style> <script type="text/javascript"> function init() { const resultSection = document.getElementById('resultSection'); const container = document.getElementById('container'); const nodeInfo = document.getElementById('nodeInfo'); let tempNode = null, selectNode = null; let startX, startY, mouseStatus; let childCount = 0; container.addEventListener("contextmenu", (e) => { e.preventDefault(); // If the right click is triggered, the target element is removed. if (e.target.className.split(" ").includes("box")) { container.removeChild(e.target); writeCurrentStatus(); } }); container.addEventListener("mousedown", (e) => { e.preventDefault(); e.target.focus(); // Save the current mouse position startX = e.clientX + window.pageXOffset; startY = e.clientY + window.pageYOffset; // 1. Select mode if (e.target.className.split(" ").includes("box")) { mouseStatus = "select"; selectNode = e.target; } else { // 2. draw mode mouseStatus = "down"; if (tempNode == null) { tempNode = document.createElement("div"); tempNode.className = "temp_node"; tempNode.style.left = startX + "px"; tempNode.style.top = startY + "px"; container.appendChild(tempNode); } } }); container.addEventListener("mouseup", (e) => { if (mouseStatus == "select") { // 1. Select mode selectNode = null; } else if (tempNode && (mouseStatus == "down" || parseInt(tempNode.style.width) * parseInt(tempNode.style.height) < 300)) { // 2. Draw mode // If no mouse move or tiny size, then the element isn't created. container.removeChild(tempNode); tempNode = null; } else if (tempNode) { tempNode.className = "box b1"; tempNode.tabIndex = 0; tempNode.innerText = String.fromCharCode(65 + childCount++); tempNode = null; } mouseStatus = "up"; writeCurrentStatus(); }); container.addEventListener("mousemove", (e) => { if (mouseStatus == "select") { // 1. Select mode selectNode.style.left = selectNode.offsetLeft - startX + e.clientX + window.pageXOffset + "px"; selectNode.style.top = selectNode.offsetTop - startY + e.clientY + window.pageYOffset + "px"; startX = e.clientX + window.pageXOffset; startY = e.clientY + window.pageYOffset; } else if (tempNode && (mouseStatus == "down" || mouseStatus == "drag")) { // 2. draw mode let currentX = e.clientX + window.pageXOffset; let currentY = e.clientY + window.pageYOffset; tempNode.style.left = ((currentX - startX < 0) ? currentX : startX) + "px"; tempNode.style.top = ((currentY - startY < 0) ? currentY : startY) + "px"; tempNode.style.width = Math.abs(currentX - startX) + "px"; tempNode.style.height = Math.abs(currentY - startY) + "px"; mouseStatus = "drag"; } }); function createElement(styleInfo) { const newElement = document.createElement("div"); ({ width: newElement.style.width, height: newElement.style.height, left: newElement.style.left, top: newElement.style.top } = styleInfo); newElement.className = "box b1"; newElement.tabIndex = "0"; newElement.innerText = String.fromCharCode(65 + childCount++); return newElement; } function writeCurrentStatus() { let nodeList = document.getElementsByClassName("box"); let currentStatus = ""; for(node of nodeList) { const styleObj = { width: node.style.width, height: node.style.height, left: node.style.left, top: node.style.top } currentStatus = currentStatus + "\n" + JSON.stringify(styleObj); } nodeInfo.value = currentStatus.trim(); } function onchangeTextarea() { const childNodes = container.children; while(container.children.length) { container.children[0].remove(); } let strArray = nodeInfo.value.trim().split("\n"); nodeInfo.value = ""; childCount = 0; for(let str of strArray) { if(str.trim().length) { const styleObj = JSON.parse(str); container.appendChild(createElement(styleObj)); nodeInfo.value = nodeInfo.value + "\n" + JSON.stringify(styleObj); } } } nodeInfo.addEventListener('change', onchangeTextarea); // Add initial element nodeInfo.value = `{"width":"80px","height":"80px","left":"212px","top":"82px"} {"width":"80px","height":"80px","left":"292px","top":"82px"} {"width":"80px","height":"80px","left":"372px","top":"82px"} {"width":"80px","height":"80px","left":"212px","top":"162px"} {"width":"80px","height":"80px","left":"292px","top":"162px"} {"width":"80px","height":"80px","left":"372px","top":"162px"}`; onchangeTextarea(); } </script> </html>