← back to Model Arena

data/artifacts/0715b25a41dd/mac1__qwen2-5vl-7b.html

137 lines

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body { font-family: sans-serif; text-align: center; margin: 50px auto; width: min(90%, calc(72vmin - 360px)); background-image: url("https://i.imgur.com/sKc4k.png"); }
        h1, p { color: #fff; font-size: clamp(24px, 3.5vh, 88px); }
        .map { height: 95%; width: 90%; position: relative; margin-top: -50px; max-width: calc(72vmin + 180px); overflow: hidden; }
        .clicker, #phrasebook {
            display: flex;
            align-items: center;
            justify-content: space-around;
            padding: 5vh 30%;
            border-radius: 5px;
            box-shadow: rgba(7,62,145,0.28) 3vmin -3px/55% 15%, inset 90deg currentColor/220% 90deg transparent;
            text-shadow: calc(inset(28vmin 18px) + outset(27.96vmin 18px));
        }
        .clicker { border-bottom-left-radius: 5px; width: min(54%, calc(64vmin - 190px)); padding-right: 5%; margin-top: auto; max-width: 320px; display: none; transition: 0.3s; }
        #phrasebook { border-bottom-right-radius: 5px; width: min(calc(78% + (54vmin - 196px) * .3), calc(85vmin )); padding-left: 2%; text-align: left; margin-top: auto; display: none; }
        button { color: #fff; background-color: transparent; border-radius: 0; height: min-content; font-size: clamp(.7em, 1.3vh, .85em); transition: transform .4s ease-in-out; outline-width: 2px; outline-style: dotted; }
        button:hover { transform: scale(1.1) translateY(-.1rem); cursor: pointer; }
        span { display: block; font-size: clamp(.76em, 1.2vh, .95em); line-height: 40%; margin-top: -3px; font-variant-numeric: tabular-nums; transition: color .4s ease-in-out; }
    </style>
    <script>
        let map, mapSize = [674, 832], speakerCount = {196: 5}; 
        const clickMapX = x => Math.round(mapWidth * (x + map.offsetLeft) / map.offsetWidth); // map's coords are shifted
        const clickMapY = y => Math.floor(mapSize[0] - (map.offsetHeight * ((y - map.offsetTop) / map.offsetHeight)) );  // the map scrolls up with mouse movement, so we flip the y axis to make everything behave as if there was no scroll; 
        document.addEventListener('scroll', () => 
            document.body.style.backgroundPosition = `${-mouseY}px`
          );
        
        let speakerId;
        const words = ["mikro", "spreken", "bontsi", "nepo"];
        const clickedWordPhrases = []; // tracks phrases with at least one word click
        
        const resetSpeakerCount = () => { 
            for (let key in speakerCount) {
                if (+key === +speakerId - 1 && speakerCount[key] <= 0)
                    delete speakerCount[key];
            }
            
            speakerId += 1; // increment speaker ID to keep track of which word we're clicking
        };
    
        function checkIfGameOver() {
            return Object.values(speakerCount).some(s => s === -2); 
        }  

        function playSound(word, index) {
            let sound = new Audio(`sounds/${word}.mp3`);
            if (checkIfGameOver()) { 
                return (speakerCount[words[index]] -= 1), document.querySelector('#clicker').textContent = `Speaker ${index}: -1`, 
                console.log(words[index], index);
            }
            
            sound.play();
        };

        let mouseX, mouseY;  
        
        function handleMouseMove(e) {
           [mouseX,mouseY] = e.target.getBoundingClientRect();
        }

        function playButtonClickHandler(e){ 
            let clickMapValue = (clickMapY(this.innerHTML)-1097)/61;
            if (words.includes(this.innerHTML)) { 
                document.querySelector('#clicker').textContent += ` "${this.innerHTML}"`; 
                words.forEach(word => resetSpeakerCount() == undefined ? console.log(word); );
              playSound(words[clickMapValue],clickMapX(clickMapValue)); 
            }
        }

        function speakerClickButtonHandler(e) {
            if (words.includes(this.textContent)) { 
                document.querySelector('#phrasebook').textContent += `${this.textContent}`; 
                const i = words.indexOf(this.textContent);
                clickedWordPhrases.push(words[i]);
            }
        }

        function setDisplayWords(w) {  
            document.querySelector('#clicker p').textContent = w;
            
            map.setAttribute('src', 'maps/wordmap/' + w + '.png');
            map.style.display = 'block';
            if (Object.keys(speakerCount).length === 0 && clickedWordPhrases.length < words.length)
                document.querySelector('.map').style.height += `${61}px`;
        }
        
        // Initialize the map and speaker
        let mapWidth; 

        function init() {
            setTimeout(() => { 
                map = document.createElement('img');
                const phrasebookDiv = document.getElementById('phrasebook');
                document.body.appendChild(map);
                document.querySelector('.clicker').addEventListener('mousemove', handleMouseMove);
                document.querySelectorAll('.clicker button').forEach(b => b.addEventListener('click', playButtonClickHandler));
                document.getElementById('phrasebook').addEventListener('click', speakerClickButtonHandler);
            }, 50); 
        }

        const initPhrasebook = () => {
            let display = `Speaker #${Object.keys(speakerCount).length}: ${words[0]}`;
            words.forEach((word, index) => { 
                if (clickedWordPhrases.includes(word)) 
                    display += ` '${word}'`;  
            });
            
            if (!Object.values(speakerCount).includes(-2))
              document.querySelector('#clicker').textContent = 'Speaker Count';
          document.getElementById('phrasebook').textContent = display;
        }
        
        init();
    </script>
</head>
<body onmousemove="handleMouseMove(e)">
<h1>Explore the Dying Language of <i>Noradon'</i></h1>

<div class="map">
  <img id="wordmap" src="maps/wordmap/mikro.png" height=50px>
</div>

<div>
    <button id="clicker">Speaker Count: -2</button>
    <p>Hover or click to explore words.</p>
</div>

<br><br>
<div id="phrasebook"></div>
    
</body>
</html>