是否将元素(尤其是右上角)固定到chrome mobile的可视视口中,内容非常广泛?

haw*_*bsl 9 mobile android css-position chromium

有没有办法将元素(特别是右上角)固定到chrome mobile的可视视口?

我们想显示网站访问者可以放大和缩小的非常大的图像。观看者需要能够看到整个图片,然后将目标对准小的区域进行检查。我们将加载比可用屏幕宽得多的图像。表示宽度从1500到6000像素。

和上面一样,我们希望在左上角和右上角有固定的导航元素。

在Webkit / Safari上,我们得到了想要的行为。

在此处输入图片说明

Chrome / Android移动版(初始加载):

在此处输入图片说明

Chrome / Android移动版(一直缩放):

在此处输入图片说明

Chrome浏览器(移动版)似乎希望将屏幕右上角的div固定到布局视口。即绿色固定的右上角div不在屏幕上,直到您一直放大到整个图片为止。

这些规格似乎暗示这是设计使然的Chrome。

从表面上看,设置minimum-scale = 1似乎可以解决此问题,但是它禁用了放大/缩小功能,因此这不是解决方案。

有没有一种解决方案可以使Chrome的行为与Webkit / Safari相同?涉及Javascript的解决方案可能可以接受。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Testing fixed width headers on mobile</title>
</head>

<style>
    .tl {
        position:fixed;
        top:0;
        left:0;
        background-color:red;
    }
    .tr {
        position:fixed;
        top:0;
        right:0;
        background-color:green;
    }
    body img {
        margin-top:110px;
    }
</style>

<body>
    <div class="tl">Fixed top left</div>
    <div class="tr">Fixed top right</div>

    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/In_the_Conservatory.jpg/1280px-In_the_Conservatory.jpg" />
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Nat*_*ies 4

最干净的解决方案是将图像放置在元素内width: 100%; overflow: auto;

对于父元素的高度,您可以使用calc(100% - X)其中 X 是导航栏的高度(假设您希望图像占据整个屏幕,除非缩小)。

请参阅下面的完整示例。

编辑:我在这个 codepen [ https://codepen.io/techslides/pen/zowLd]的帮助下更新了下面的答案,用于在画布元素内进行缩放和平移。您还可以添加事件侦听器来检查窗口大小调整并根据需要重新绘制画布。

var canvas = document.getElementsByTagName('canvas')[0];
canvas.width = window.innerWidth;
canvas.height = window.innerHeight - 20;

var canvasimage = new Image;

window.onload = function() {

  var ctx = canvas.getContext('2d');
  trackTransforms(ctx);

  function redraw() {

    // Clear the entire canvas
    var p1 = ctx.transformedPoint(0, 0);
    var p2 = ctx.transformedPoint(canvas.width, canvas.height);
    ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);

    ctx.save();
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.restore();

    ctx.drawImage(canvasimage, 0, 0);

  }
  redraw();

  var lastX = canvas.width / 2,
    lastY = canvas.height / 2;

  var dragStart, dragged;

  canvas.addEventListener('mousedown', function(evt) {
    document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
    lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
    lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
    dragStart = ctx.transformedPoint(lastX, lastY);
    dragged = false;
  }, false);

  canvas.addEventListener('mousemove', function(evt) {
    lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
    lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
    dragged = true;
    if (dragStart) {
      var pt = ctx.transformedPoint(lastX, lastY);
      ctx.translate(pt.x - dragStart.x, pt.y - dragStart.y);
      redraw();
    }
  }, false);

  canvas.addEventListener('mouseup', function(evt) {
    dragStart = null;
    if (!dragged) zoom(evt.shiftKey ? -1 : 1);
  }, false);

  var scaleFactor = 1.1;

  var zoom = function(clicks) {
    var pt = ctx.transformedPoint(lastX, lastY);
    ctx.translate(pt.x, pt.y);
    var factor = Math.pow(scaleFactor, clicks);
    ctx.scale(factor, factor);
    ctx.translate(-pt.x, -pt.y);
    redraw();
  }

  var handleScroll = function(evt) {
    var delta = evt.wheelDelta ? evt.wheelDelta / 40 : evt.detail ? -evt.detail : 0;
    if (delta) zoom(delta);
    return evt.preventDefault() && false;
  };

  canvas.addEventListener('DOMMouseScroll', handleScroll, false);
  canvas.addEventListener('mousewheel', handleScroll, false);
};

canvasimage.src = 'https://i.stack.imgur.com/ITUHK.png';

// Adds ctx.getTransform() - returns an SVGMatrix
// Adds ctx.transformedPoint(x,y) - returns an SVGPoint
function trackTransforms(ctx) {
  var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
  var xform = svg.createSVGMatrix();
  ctx.getTransform = function() {
    return xform;
  };

  var savedTransforms = [];
  var save = ctx.save;
  ctx.save = function() {
    savedTransforms.push(xform.translate(0, 0));
    return save.call(ctx);
  };

  var restore = ctx.restore;
  ctx.restore = function() {
    xform = savedTransforms.pop();
    return restore.call(ctx);
  };

  var scale = ctx.scale;
  ctx.scale = function(sx, sy) {
    xform = xform.scaleNonUniform(sx, sy);
    return scale.call(ctx, sx, sy);
  };

  var rotate = ctx.rotate;
  ctx.rotate = function(radians) {
    xform = xform.rotate(radians * 180 / Math.PI);
    return rotate.call(ctx, radians);
  };

  var translate = ctx.translate;
  ctx.translate = function(dx, dy) {
    xform = xform.translate(dx, dy);
    return translate.call(ctx, dx, dy);
  };

  var transform = ctx.transform;
  ctx.transform = function(a, b, c, d, e, f) {
    var m2 = svg.createSVGMatrix();
    m2.a = a;
    m2.b = b;
    m2.c = c;
    m2.d = d;
    m2.e = e;
    m2.f = f;
    xform = xform.multiply(m2);
    return transform.call(ctx, a, b, c, d, e, f);
  };

  var setTransform = ctx.setTransform;
  ctx.setTransform = function(a, b, c, d, e, f) {
    xform.a = a;
    xform.b = b;
    xform.c = c;
    xform.d = d;
    xform.e = e;
    xform.f = f;
    return setTransform.call(ctx, a, b, c, d, e, f);
  };

  var pt = svg.createSVGPoint();
  ctx.transformedPoint = function(x, y) {
    pt.x = x;
    pt.y = y;
    return pt.matrixTransform(xform.inverse());
  }
}
Run Code Online (Sandbox Code Playgroud)
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.wide {
  width: 200vw;
}

.nav {
  width: 100%;
  height: 20px;
}

.clearfix::after {
  content: "";
  clear: both;
  display: table;
}

.left-nav {
  background-color: red;
}

.right-nav {
  float: right;
  background-color: green;
}
Run Code Online (Sandbox Code Playgroud)
<div class="nav clearfix">
  <span class="left-nav">Top Left</span>
  <span class="right-nav">Top Right</span>
</div>
<canvas>
        </canvas>
Run Code Online (Sandbox Code Playgroud)