javascripthtmlcssimage

Image not drawning correctly in <img>


I'm loading an image from a server. I've confirmed that the whole file is downloading. The first image is what is being displayed the second image is what the server has. Notice that the top 10%(ish) is missing, from the displayed image.

The HTML body, code and css

<body>
<!-- Image -->
<div id="worldMapContainer" class="world-map-container">
    
</div>

<!-- Zoom control buttons -->
<div class="zoom-controls">
    <button class="zoom-button" onclick="setZoom('fit')">
        <img src="assets/fullscreen-icon.png" alt="Fit to Screen" title="Fit to Screen" />
    </button>
    <div class="zoom-levels">
        <button onclick="setZoom(1)">1x</button>
        <button onclick="setZoom(5)">2x</button>
        <button id="zoom-3x" onclick="setZoom(10)">3x</button>
        <button onclick="setZoom(15)">4x</button>
    </div>
</div>
</body>

.world-map-container {
    position: relative;
    margin-left: 10px;
    margin-top: 20px;
    margin-right: 10px;
    width: 85vw;
    height: 85vh;
    overflow: auto;
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Image styling */
.world-map-container img {
    display: block;
    max-width: none;
    max-height: none;
    image-rendering: pixelated; /* Preserve pixelated effect when scaled */
    image-rendering: crisp-edges; /* Fallback for some browsers */
}

async onWorldMap(msg) {
    const imageData = `data:image/png;base64,${this.arrayBufferToBase64(msg.params.image.data)}`
    console.log('download: ', imageData.length)

    localStorage.setItem("mapData", imageData)
    localStorage.setItem("mapWidth", msg.params.width.toString())
    localStorage.setItem("mapHeight", msg.params.height.toString())

    this.loadImageFromLocalStorage('mapData')
}

arrayBufferToBase64(buffer) {
    let binary = ''        
    const bytes = new Uint8Array(buffer)
    const len = bytes.length
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i])
    }
    return btoa(binary)
}

loadImageFromLocalStorage(key) {
    this.map = localStorage.getItem(key)

    if (this.map) {
        console.log('load: ' + this.map.length)
        this.width = parseInt(localStorage.getItem('mapWidth'))
        this.height = parseInt(localStorage.getItem('mapHeight'))

        this.mapImage = document.createElement("img")
        this.mapContainer = document.getElementById("worldMapContainer")
         
        this.mapImage.id = 'worldMap'
        this.mapImage.alt = 'World Map'
        this.mapImage.src = this.map
        this.mapImage.width = this.width
        this.mapImage.height = this.height
        this.mapContainer.appendChild(this.mapImage)
    }
}

Any thoughts would be appreciated, I'm fairly new to web programming. loaded image

server image


Solution

  • Updated answer

    Turns out align-items: center; in .world-map-container was shifting the image upwards to vertically align its center to the container. Removing this previews the whole image in its scrollable container.

    <head>
        <style>
            .world-map-container {
                position: relative;
                margin-left: 10px;
                margin-top: 20px;
                margin-right: 10px;
                width: 85vw;
                height: 85vh;
                overflow: auto;
                display: flex;
                justify-content: center;
                /* align-items: center; */
            }
            
            /* Image styling */
            .world-map-container img {
                display: block;
                max-width: none;
                max-height: none;
                image-rendering: pixelated; /* Preserve pixelated effect when scaled */
                image-rendering: crisp-edges; /* Fallback for some browsers */
            }
        </style>
    </head>
    
    <body>
        <!-- Image -->
        <div id="worldMapContainer" class="world-map-container">
            
        </div>
        
        <!-- Zoom control buttons -->
        <div class="zoom-controls">
            <button class="zoom-button" onclick="setZoom('fit')">
                <img src="assets/fullscreen-icon.png" alt="Fit to Screen" title="Fit to Screen" />
            </button>
            <div class="zoom-levels">
                <button onclick="setZoom(1)">1x</button>
                <button onclick="setZoom(5)">2x</button>
                <button id="zoom-3x" onclick="setZoom(10)">3x</button>
                <button onclick="setZoom(15)">4x</button>
            </div>
        </div>
    
    
        <script>
            wat = {"params": {"width": 1000, "height": 1000}}
            onWorldMap(wat)
            
            async function onWorldMap(msg) {
                // const imageData = `data:image/png;base64,${this.arrayBufferToBase64(msg.params.image.data)}`
                const imageData = `https://i.sstatic.net/kE32sxOb.png`
                console.log('download: ', imageData.length)
    
                localStorage.setItem("mapData", imageData)
                localStorage.setItem("mapWidth", msg.params.width.toString())
                localStorage.setItem("mapHeight", msg.params.height.toString())
    
                this.loadImageFromLocalStorage('mapData')
            }
    
            function arrayBufferToBase64(buffer) {
                let binary = ''        
                const bytes = new Uint8Array(buffer)
                const len = bytes.length
                for (let i = 0; i < len; i++) {
                    binary += String.fromCharCode(bytes[i])
                }
                return btoa(binary)
            }
    
            function loadImageFromLocalStorage(key) {
                this.map = localStorage.getItem(key)
    
                if (this.map) {
                    console.log('load: ' + this.map.length)
                    this.width = parseInt(localStorage.getItem('mapWidth'))
                    this.height = parseInt(localStorage.getItem('mapHeight'))
    
                    this.mapImage = document.createElement("img")
                    this.mapContainer = document.getElementById("worldMapContainer")
                    
                    this.mapImage.id = 'worldMap'
                    this.mapImage.alt = 'World Map'
                    this.mapImage.src = this.map
                    this.mapImage.width = this.width
                    this.mapImage.height = this.height
                    this.mapContainer.appendChild(this.mapImage)
                }
            }
        </script>
    </body>
    

    How the webpage looks to me using wat = {"params": {"width": 1000, "height": 1000}} enter image description here



    Old answer

    In your CSS, .world-map-container is using height: 85vh; width: 85vw; which isn't large enough to contain your image. Removing them will allow the entire image to be displayed.

    Try out my example below:

    <head>
        <style>
            .world-map-container {
                position: relative;
                margin-left: 10px;
                margin-top: 20px;
                margin-right: 10px;
                /* Uses only 85% of the viewport. Your image size exceeds this */
                /* width: 85vw; */
                /* height: 85vh; */
                overflow: auto;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            
            /* Image styling */
            .world-map-container img {
                display: block;
                max-width: none;
                max-height: none;
                image-rendering: pixelated; /* Preserve pixelated effect when scaled */
                image-rendering: crisp-edges; /* Fallback for some browsers */
            }
        </style>
    </head>
    
    <body>
        <!-- Image -->
        <div id="worldMapContainer" class="world-map-container">
            
        </div>
        
        <!-- Zoom control buttons -->
        <div class="zoom-controls">
            <button class="zoom-button" onclick="setZoom('fit')">
                <img src="assets/fullscreen-icon.png" alt="Fit to Screen" title="Fit to Screen" />
            </button>
            <div class="zoom-levels">
                <button onclick="setZoom(1)">1x</button>
                <button onclick="setZoom(5)">2x</button>
                <button id="zoom-3x" onclick="setZoom(10)">3x</button>
                <button onclick="setZoom(15)">4x</button>
            </div>
        </div>
    
    
        <script>
            wat = {"params": {"width": 4000, "height": 4000}}
            onWorldMap(wat)
            
            async function onWorldMap(msg) {
                // const imageData = `data:image/png;base64,${this.arrayBufferToBase64(msg.params.image.data)}`
                const imageData = `https://i.sstatic.net/kE32sxOb.png`
                console.log('download: ', imageData.length)
    
                localStorage.setItem("mapData", imageData)
                localStorage.setItem("mapWidth", msg.params.width.toString())
                localStorage.setItem("mapHeight", msg.params.height.toString())
    
                this.loadImageFromLocalStorage('mapData')
            }
    
            function arrayBufferToBase64(buffer) {
                let binary = ''        
                const bytes = new Uint8Array(buffer)
                const len = bytes.length
                for (let i = 0; i < len; i++) {
                    binary += String.fromCharCode(bytes[i])
                }
                return btoa(binary)
            }
    
            function loadImageFromLocalStorage(key) {
                this.map = localStorage.getItem(key)
    
                if (this.map) {
                    console.log('load: ' + this.map.length)
                    this.width = parseInt(localStorage.getItem('mapWidth'))
                    this.height = parseInt(localStorage.getItem('mapHeight'))
    
                    this.mapImage = document.createElement("img")
                    this.mapContainer = document.getElementById("worldMapContainer")
                    
                    this.mapImage.id = 'worldMap'
                    this.mapImage.alt = 'World Map'
                    this.mapImage.src = this.map
                    this.mapImage.width = this.width
                    this.mapImage.height = this.height
                    this.mapContainer.appendChild(this.mapImage)
                }
            }
        </script>
    </body>
        
    

    How the webpage looks to me using wat = {"params": {"width": 700, "height": 700}} enter image description here