ZEISS
ZEN navx 2.0
  • Information Architecture
  • Interface Design
  • UIUX
  • 3D Animations
  • Creative Direction
The Client's Challenge

Build upon the success of ZEN navx 1.0, enhance the interface design, usability, and the end to end workflow for ZEISS Versa operators. Bring cognitive clarity to the Scout & Scan dashboard as a central decision point for all operators, and update the core nav experience for the macro and micro steps to improve the experience and yield better results for global non-destructive imaging based research.

zeiss.com
The Design Approach

Evolving the core left-hand navigation paradigm was a complex but ultimately rewarding creative solution, leveraging an expand/collapse visualization to reinforce macro and micro steps, while solving workflow complexities from the prior version.

For the Scout & Scan dashboard we conceived and designed custom 3D animations that provide clearer representation of the choices available to operators. We continue to work closely with the ZEISS team to ensure ZEN navx evolves as we iteratively learn from operators, to ensure it remains best-in-class.

Before
After
Optimized Workflows + Grid

With 2.0 we have further optimized the underlying grid that creates order and hierarchy to the interface design. A refreshed left hand nav now creates clarity to the macro and micro steps, and delivers more pixels so the images can be the focal point of the experience.


<!-- 💙 MEMBERSCRIPT #112 v0.1 💙 - BEFORE & AFTER SLIDERS -->
<script>
document.addEventListener('DOMContentLoaded', () => {
    const wraps = document.querySelectorAll('[ms-code-ba-wrap]');

    wraps.forEach(wrap => {
        const before = wrap.querySelector('[ms-code-ba-before]');
        const after = wrap.querySelector('[ms-code-ba-after]');
        
        // Create slider element
        const slider = document.createElement('div');
        slider.setAttribute('ms-code-ba-slider', wrap.getAttribute('ms-code-ba-wrap'));
        wrap.appendChild(slider);

        let isDown = false;

        // Ensure proper positioning
        wrap.style.position = 'relative';
        wrap.style.overflow = 'hidden';
        before.style.width = '100%';
        before.style.display = 'block';
        after.style.position = 'absolute';
        after.style.top = '0';
        after.style.left = '0';
        after.style.width = '100%';
        after.style.height = '100%';
        slider.style.position = 'absolute';
        slider.style.top = '0';
        slider.style.bottom = '0';
        slider.style.width = '4px';
        slider.style.background = 'white';
        slider.style.cursor = 'ew-resize';
        slider.style.zIndex = '3';

        const setPosition = (position) => {
            const clampedPosition = Math.max(0, Math.min(1, position));
            slider.style.left = `${clampedPosition * 100}%`;
            after.style.clipPath = `inset(0 0 0 ${clampedPosition * 100}%)`;
        };

        const move = (e) => {
            if (!isDown && e.type !== 'mousemove') return;
            e.preventDefault();

            const x = e.type.includes('touch') ? e.touches[0].clientX : e.clientX;
            const rect = wrap.getBoundingClientRect();
            const position = (x - rect.left) / rect.width;
            
            setPosition(position);
        };

        const easeBack = () => {
            setPosition(0.5); // Move back to center
        };

        wrap.addEventListener('mousedown', () => isDown = true);
        wrap.addEventListener('mouseup', () => isDown = false);
        wrap.addEventListener('mouseleave', () => {
            isDown = false;
            easeBack();
        });
        wrap.addEventListener('mousemove', move);

        wrap.addEventListener('touchstart', (e) => {
            isDown = true;
            move(e);
        });
        wrap.addEventListener('touchmove', move);
        wrap.addEventListener('touchend', () => {
            isDown = false;
            easeBack();
        });

        // Initialize position
        setPosition(0.5);
    });
});
</script>
Text Link