2015-10-27 9 views
5

Próbuję wyświetlić obraz przy użyciu symulacji cover w obszarze roboczym. Znalazłem fajne answer, jak to zrobić.Uzyskiwanie brzydkiego obrazu podczas symulowania okładki na płótnie

Chodzi o to, kiedy robię to z dużym obrazem, to jest wyświetlane brzydko. Jak to naprawić?

Oto mój 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); 
} 
+0

W pierwszym miejscu, jaki jest powód, dla którego chcesz wyświetlać obraz na płótnie, a nie tylko z podstawowym html/css? Na przykład: 'background-size: cover;' Przykłady tego można znaleźć [tutaj] (https://css-tricks.com/perfect-full-page-background-image/) i wiele więcej .. –

Odpowiedz

3

Aby to osiągnąć, można użyć kilku technik, takich jak HTML/CSS, tylko CSS, Jquery lub JS/Canvas. Więcej informacji na ten temat: look here.

Nie musisz ani ustawić szerokości i wysokości płótna w HTML, jak wspomniany David Skx. Musisz wymazać swój CSS, całkowicie go usunąć.

W swoim JS należy ustawić rozmiar płótna (wystarczy zdefiniować go w 1 miejscu, niech nie przeszkadzają różne języki):

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

Okno oznacza całą przeglądarkę, użyj pikseli tutaj, jeśli chcesz ogranicz to tylko do płótna, a nie całego tła.

To wszystko.

+0

Czy możesz przepisać mój kodepan? –

+0

Nie musi zmieniać rozmiaru samodzielnie. –

+0

po prostu wklej "canvas.width = window.innerWidth; canvas.height = window.innerHeight; 'na linii 3 twojego JS i gotowe, chyba że chcesz mieć płótno o określonej wielkości, np. 500 × 900 użyjesz' canvas.width = 500; canvas.height = 900; ' I nie zapomnij usunąć swojego css .. –

2

Musisz określić szerokość i wysokość w pikselach bezpośrednio na <canvas> -elementowe, inaczej będzie go zniekształcać:

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

Wykorzystanie JavaScript, żeby zmierzyć szerokość i wysokość okna i ustawić go dynamicznie. Coś jak:

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

UPDATE: Jak Matthijs van Hest wskazał, szerokość i wysokość atrybuty na <canvas> -elementowe to tylko opcja.

+1

Ty nie wiesz t musi określać szerokość i wysokość, może tylko pomóc w zapobieganiu, by przeglądarka nie potknęła się w tym ułamku sekundy od utworzenia DOM do wykonania JS. Ponadto; Twój JS powinien być krótszy i bardziej czytelny, jak w mojej odpowiedzi....... keep your neath –

+0

Oczywiście, że masz prawo. Chciałem tylko wskazać, że jeśli używana jest właściwość width i height, muszą to być absolutne piksele. – misantronic

+0

Cóż, twoja sprawa "działała", ale po prostu nie wspomniałeś o tym wszystkim, a twój kod mógł zostać poprawiony, dlatego stworzyłem własną odpowiedź na to pytanie. A jednak dobrze jest zwracać uwagę na rzeczy, nigdy nie zapominaj, że głównym celem jest odpowiedź na pytanie <3 –