【问题标题】:Getting ugly image while simulating cover in canvas在画布中模拟封面时得到丑陋的图像
【发布时间】:2016-01-26 17:23:03
【问题描述】:

我正在尝试在画布中使用cover 模拟显示图像。我找到了一些很酷的 answer 来告诉我怎么做。

问题是,当我使用大图片时,它会显示得很丑。如何解决?

这是我的Codepen

HTML

<canvas id="canvas"></canvas>

CSS

    canvas {
      width: 100%;
      height: 100vh;
    }

JS

var ctx = canvas.getContext('2d'),
    img = new Image;

img.onload = draw;
img.src = 'https://upload.wikimedia.org/wikipedia/commons/0/0f/2010-02-19_3000x2000_chicago_skyline.jpg';

function draw() {
    drawImageProp(ctx, this, 0, 0, canvas.width, canvas.height);
    //drawImageProp(ctx, this, 0, 0, canvas.width, canvas.height, 0.5, 0.5);
}

/**
 * By Ken Fyrstenberg
 *
 * drawImageProp(context, image [, x, y, width, height [,offsetX, offsetY]])
 *
 * If image and context are only arguments rectangle will equal canvas
*/
function drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {

    if (arguments.length === 2) {
        x = y = 0;
        w = ctx.canvas.width;
        h = ctx.canvas.height;
    }

    /// default offset is center
    offsetX = offsetX ? offsetX : 0.5;
    offsetY = offsetY ? offsetY : 0.5;

    /// keep bounds [0.0, 1.0]
    if (offsetX < 0) offsetX = 0;
    if (offsetY < 0) offsetY = 0;
    if (offsetX > 1) offsetX = 1;
    if (offsetY > 1) offsetY = 1;

    var iw = img.width,
        ih = img.height,
        r = Math.min(w / iw, h / ih),
        nw = iw * r,   /// new prop. width
        nh = ih * r,   /// new prop. height
        cx, cy, cw, ch, ar = 1;

    /// decide which gap to fill    
    if (nw < w) ar = w / nw;
    if (nh < h) ar = h / nh;
    nw *= ar;
    nh *= ar;

    /// calc source rectangle
    cw = iw / (nw / w);
    ch = ih / (nh / h);

    cx = (iw - cw) * offsetX;
    cy = (ih - ch) * offsetY;

    /// make sure source rectangle is valid
    if (cx < 0) cx = 0;
    if (cy < 0) cy = 0;
    if (cw > iw) cw = iw;
    if (ch > ih) ch = ih;

    /// fill image in dest. rectangle
    ctx.drawImage(img, cx, cy, cw, ch,  x, y, w, h);
}

【问题讨论】:

  • 首先,您想在画布中显示图像而不仅仅是基本的 html/css 的原因是什么?喜欢:background-size: cover; 这方面的例子可以找到here 等等..

标签: javascript html css canvas


【解决方案1】:

要实现这一点,您可以使用多种技术,例如 HTML/CSS、仅 CSS、Jquery 或 JS/Canvas。有关此look here 的更多信息。

您确实必须像 David Skx 提到的那样在 HTML 中设置画布的宽度和高度。你必须删除你的 CSS,完全删除它。

在你的 JS 中你应该设置你的画布大小(只需在 1 个地方定义它,不要让不同的语言干扰):

var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth; 
canvas.height = window.innerHeight;

窗口意味着整个浏览器,如果你想将其限制在画布上而不是整个背景,请在此处使用像素

就是这样。

【讨论】:

  • 它不必按比例调整自己的大小。
  • 只需在 JS 的第 3 行粘贴 canvas.width = window.innerWidth; canvas.height = window.innerHeight; 就完成了,除非你想要一个特定大小的画布,比如 500×900,你使用 canvas.width = 500; canvas.height = 900; 并且不要忘记删除你的 CSS ..
【解决方案2】:

您必须直接在&lt;canvas&gt;-Element 上以像素为单位指定宽度和高度,否则它会扭曲它:

<canvas id="canvas" width="500" height="500"></canvas>

使用 JavaScript 测量窗口的宽度和高度并动态设置。比如:

var canvas = document.getElementById('canvas');
canvas.setAttribute('width', window.innerWidth);
canvas.setAttribute('height', window.innerHeight);

更新: 正如 Matthijs van Hest 所指出的,&lt;canvas&gt;-元素的宽度和高度属性只是可选的。

【讨论】:

  • 您不必指定宽度和高度,它只能帮助防止浏览器视图从创建 DOM 到执行 JS 的那一瞬间跳闸。此外;你的 JS 应该像我的回答一样更短、更易读。保持整洁
  • 当然是你的权利。我只是想指出,如果使用 width 和 height 属性,它必须是绝对像素。
  • 嗯,你的东西确实“有效”,但你只是没有提到这一切,你的代码可以改进,这就是为什么我对这个问题做出自己的回答。然而,指出一些事情是好的,永远不要忘记主要目标是回答一个问题
猜你喜欢
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多