CSS hareketli grafiğindeki bir görüntüyü nasıl ölçeklendirebilirim?


157

Bu makalede, http://css-tricks.com/css-sprites/ , daha büyük bir görüntüden daha küçük bir görüntüyü nasıl kırpabileceğimden bahsediyor. Lütfen mümkün olup olmadığını / daha küçük bir görüntüyü nasıl kırpabileceğimi ve sonra kırpmadan önce kırpılan bölgeyi nasıl ölçeklendirebileceğimi söyleyebilir misiniz?

İşte bu makaleden bir örnek:

A
{
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

Spriteme1.png'den kırptıktan sonra bu görüntüyü nasıl ölçeklendirebileceğimi bilmek istiyorum

Örneğin URL'si: http://css-tricks.com/examples/CSS-Sprites/Example1After/

Öyleyse Öğe1,2,3,4'ün yanındaki simgeleri küçültebilir miyim bilmek istiyorum?


Stephen'ın dediği gibi, görüntüleri ilk başta istediğiniz boyutta oluşturmanızı engelleyen bir şey var mı?
Paul D.Waite

4
Aynı şey için bir cevap aradığımdan beri bu sayfayı buldum. Yüksek çözünürlüklü retina ekranlı bugünün dünyasında olması gerekenden iki kat daha büyük bir görüntü oluşturmak gelenekseldir ve daha sonra, görüntüleme sırasında yüksekliğin / genişliğin yarısına indirmek için <img> niteliklerinde veya CSS stillerinde yükseklik / genişlik değerleri kullanın. Bu, akıllı telefonlarda ve tabletlerde net görüntü sağlar. Ancak PNG sprite'ları hızlı bir şekilde önbelleğe almak ve oluşturmak için mükemmeldir. Sadece 2x görüntüden oluşan bir hareketli grafik kullanmak değil, aynı zamanda daha net görünmesini sağlayan bir boyuta ölçeklendirmek de en iyisidir.
Art Geigel

Orijinal soru asla kabul edilen bir cevap almadığından ve oldukça düzgün ve geriye dönük uyumlu bir çözüm olduğundan, orijinal web sitesi artık çevrimiçi olmadığı için yeni bir Codepen Stretchy sürümü yaptım ve maaaaybe hala geriye ihtiyaç duyan bazı insanlar var uyumlu çözüm. Kalemi orijinal eserin / yazarın atıfıyla yaptım.
Tüm Bitler

Yanıtlar:


131

Çoğu tarayıcı tarafından desteklendiği için arka plan boyutunu kullanabilirsiniz (ancak tüm http://caniuse.com/#search=background-size )

background-size : 150% 150%;

Veya

Webkit / ie için bir zoom kombinasyonu kullanabilirsiniz ve dönüşümü yapabilirsiniz: tarayıcılar arası masaüstü ve mobil cihazlar için Firefox (-moz-) ve Opera (-o-) için ölçek

[class^="icon-"]{
    display: inline-block;
    background: url('../img/icons/icons.png') no-repeat;
    width: 64px;
    height: 51px;
    overflow: hidden;
    zoom:0.5;
    -moz-transform:scale(0.5);
    -moz-transform-origin: 0 0;
}

.icon-huge{
    zoom:1;
    -moz-transform:scale(1);
    -moz-transform-origin: 0 0;
}

.icon-big{
    zoom:0.60;
    -moz-transform:scale(0.60);
    -moz-transform-origin: 0 0;
}

.icon-small{
    zoom:0.29;
    -moz-transform:scale(0.29);
    -moz-transform-origin: 0 0;
}

3
Chrome'da harika çalışıyor, FF, IE9 / 10'da Tamam çalışıyor. Çoğunlukla istenen etkiyi üretir.
RCNeil

(Örnek) arka plan boyutunu kullanma:% 15; doğru en boy oranını korurken sprite için mükemmel çalışır. Duyarlı sitelerdeki kesme noktalarıyla kullanmak için basit bir çözümdür.
C13L0

1
arka plan boyutu özelliği sabit bir yükseklik ve genişlik ile benim svg sprite için işe yaramadı, ancak ölçek hile yaptı.
Andre

IE8'e destek eklemek için, IE8 Standartları kipinde eşanlamlı olarak -ms-zoom özniteliğini kullanın. -ms-zoom: 0.7; Daha fazla ayrıntı için aşağıdaki bağlantıya bakın: msdn.microsoft.com/en-us/library/ms531189(v=vs.85).aspx
Amr

2
2017 güncellemesi: arka plan boyutu IE9 + dahil tüm büyük tarayıcılar tarafından desteklenir. caniuse.com/#search=background-size
Nathan Hinchey

29

Sprite kullandığınızda, hareketli grafikteki görüntünün boyutları ile sınırlandırılırsınız. background-sizeStephen bahsettiği CSS özelliği, yaygın henüz desteklenmiyor ve IE8 gibi ve aşağıdaki tarayıcılarla sorunlara neden olabilir - ve bunların pazar payı göz önüne alındığında, bu uygun bir seçenek değildir.

Sorunu çözmenin bir başka yolu, iki öğe kullanmak ve hareketli grafiği aşağıdaki imggibi bir etiketle ölçeklendirmektir :

<div class="sprite-image"
     style="width:20px; height:20px; overflow:hidden; position:relative">
    <!-- set width/height proportionally, to scale the sprite image -->
    <img src="sprite.png" alt="icon"
         width="20" height="80"
         style="position:absolute; top: -20px; left: 0;" />
</div>

Bu şekilde, dış eleman ( div.sprite-image), imgölçeklendirilmiş gibi davranan etiketten 20x20 piksel boyutunda bir resim kırpıyor background-image.


2
Buradaki cletus ve Quentin statet gibi , bu en iyi yaklaşım olmayabilir. Benim için bu bir anlaşma kırıcı - srccss ile atamam gerekiyor .
Jook

-1: Sunum öğelerini içerik / verilerle karıştıramazsınız. <img>yalnızca içeriğin bir parçasıysa kullanılmalıdır. tasarım amacıyla, arka plan görüntüleri bir zorunluluktur.
Shahriyar Imanov

En iyi cevap (a) evrensel olarak çalışır, (b) insanlar tarafından anlaşılır, (c) kısadır, ... (z) sunumu içerikten ayırır.
Bob Stein

18

Şunu deneyin: Esnek Spritelar - Çapraz tarayıcı, CSS hareketli resimlerinin duyarlı yeniden boyutlandırma / esneme

Bu yöntem, sprite'ları 'yanıt olarak' ölçeklendirir, böylece genişlik / yükseklik tarayıcınızın pencere boyutuna göre ayarlanır. Bu kullanmaz background-size olarak destek eski tarayıcılarda bunun için varolmayan.

CSS

.stretchy {display:block; float:left; position:relative; overflow:hidden; max-width:160px;}
.stretchy .spacer {width: 100%; height: auto;}
.stretchy .sprite {position:absolute; top:0; left:0; max-width:none; max-height:100%;}
.stretchy .sprite.s2 {left:-100%;}
.stretchy .sprite.s3 {left:-200%;}

HTML

<a class="stretchy" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>
<a class="stretchy s2" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>
<a class="stretchy s3" href="#">
  <img class="spacer" alt="" src="spacer.png">
  <img class="sprite" alt="icon" src="sprite_800x160.jpg">
</a>

3
Bağlantı, buradaki teoriyi gerçekten açıklamıyor. Taşma görüntüsünün ölçeklendirilmiş bir sürümünü kullanmanın üzerinde bir kırpma alanı / penceresi olarak gizlenmiş taşma: bir div kullanıyorsunuz. Bu yüzden arka plan resmi kullanmıyor. Maske olarak sadece bir katman diğerinin üzerine.
Simon

1
aralayıcı bir resim olmalı mı yoksa bunun yerine basit bir div kullanılabilir mi?
isapir

4
İşte bunun bir CodePen örneği. Sadece yatay veya dikey spritelar için çalışıyor gibi görünüyor. Izgaralar değil.
Wernight

Orijinal web sitesi artık çevrimiçi olmadığı için yeni bir Codepen Stretchy sürümü yaptım ve maaaaybe hala geriye dönük uyumlu bir çözüme ihtiyaç duyan bazı insanlar var. Kalemi orijinal eserin / yazarın
All Bits Equal

10

transform: scale(); orijinal elemanın boyutunu koruyacaktır.

En iyi seçenek kullanmak olduğunu buldum vw. Bir cazibe gibi çalışıyor:

https://jsfiddle.net/tomekmularczyk/6ebv9Lxw/1/

#div1,
#div2,
#div3 {
  background:url('//www.google.pl/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png') no-repeat;
  background-size: 50vw;   
  border: 1px solid black;
  margin-bottom: 40px;
}

#div1 {
  background-position: 0 0;
  width: 12.5vw;
  height: 13vw;
}
#div2 {
  background-position: -13vw -4vw;
  width: 17.5vw;
  height: 9vw;
  transform: scale(1.8);
}
#div3 {
  background-position: -30.5vw 0;
  width: 19.5vw;
  height: 17vw;
}
<div id="div1">
  </div>
  <div id="div2">
  </div>
  <div id="div3">
  </div>


Merhaba bu soruya cevap vermiyor. Üç div'i aynı görüntünün farklı ölçekleriyle göstermelisiniz. Birkaç kelimeyle, "yazı tipi" nin farklı boyutlarını göstermelidir. Tamir edebilir misin?
Robert

merhaba @Robert. Şimdi nasıl?
Tomasz Mularczyk

PS, VW ölçü birimini kullanarak davranışları fark ettiniz mi?
Robert

Emin değilim, ne tür davranışlar demek istiyorsun?
Tomasz Mularczyk

VW VH, görüntü alanı boyutuyla orantılı olarak ölçekleniyor. Onları şimdiye kadar hiç kullanmadım. Bu sadece onları kullanma deneyiminizle ilgili bir meraktır. Bu kadar "sihirli" mi yoksa fark etmiş olabileceğiniz bazı durumlarda (beklenmedik davranışlar) dikkate alınması gereken konular var mı? teşekkür ederim
Robert

7

İşte bunu yapmak için yaptım. IE8 ve altı sürümlerde çalışmayacağını unutmayın.

#element {
  width:100%;
  height:50px;
  background:url(/path/to/image.png);
  background-position:140.112201963534% 973.333333333333%;
}

Arka plan resminin genişliği, #elementölçeklerin üst öğesi olarak küçülür. Yüzdeye dönüştürürseniz, yüksekliği ile de aynısını yapabilirsiniz height. Sadece zor bit için yüzdeleri bulmak background-position.

İlk yüzde, normal genişlikte hareketli grafiğin toplam genişliğine bölünüp 100 ile çarpıldığında hareketli grafiğin hedeflenen alanının genişliğidir.

İkinci yüzde, ölçeklendirilmeden önce hareketli grafiğin hedeflenen alanının yüksekliğinin hareketli grafiğin toplam yüksekliğine bölünmesi ve 100 ile çarpılmasıdır.

Bu iki denklemdeki ifadeler biraz özensiz, bu yüzden daha iyi açıklamam için bana ihtiyacınız varsa bildirin.


6

Bu benim için işe yarıyor gibi görünüyor.

Spritelar ızgaradaysa, background-size% 100 sprite sayısını ve% 100 sprite sayısını aşağıya ayarlayın. Sonra background-position -<x*100>% -<y*100>%x ve y sıfır tabanlı hareketli grafik

Diğer bir deyişle, soldaki 3. ve 2. satırdan 2 ve 1 aşağı olan sprite

background-position: -200% -100%;

Örneğin, 4x2 sprite bir sprite sayfası

resim açıklamasını buraya girin

Ve işte bir örnek

div {
  margin: 3px;
  display: inline-block;
}
.sprite {
  background-image: url('https://i.stack.imgur.com/AEYNC.png');
  background-size: 400% 200%;  /* 4x2 sprites so 400% 200% */
}
.s0x0 { background-position:    -0%   -0%; }
.s1x0 { background-position:  -100%   -0%; }
.s2x0 { background-position:  -200%   -0%; }
.s3x0 { background-position:  -300%   -0%; }
.s0x1 { background-position:    -0%  -100%; }
.s1x1 { background-position:  -100%  -100%; }
.s2x1 { background-position:  -200%  -100%; }
.s3x1 { background-position:  -300%  -100%; }
<div class="sprite s3x1" style="width: 45px; height:20px"></div>
<div class="sprite s3x1" style="width: 128px; height:30px"></div>
<div class="sprite s3x1" style="width: 64px; height:56px"></div>
<div class="sprite s2x1" style="width: 57px; height:60px"></div>
<div class="sprite s3x0" style="width: 45px; height:45px"></div>
<div class="sprite s0x1" style="width: 12px; height:100px"></div>

<br/>
<div class="sprite s0x0" style="width: 45px; height:20px"></div>
<div class="sprite s1x0" style="width: 128px; height:45px"></div>
<div class="sprite s2x0" style="width: 64px; height:56px"></div>
<div class="sprite s3x0" style="width: 57px; height:60px"></div>
<br/>
<div class="sprite s0x1" style="width: 45px; height:45px"></div>
<div class="sprite s1x1" style="width: 12px; height:50px"></div>
<div class="sprite s2x1" style="width: 12px; height:50px"></div>
<div class="sprite s3x1" style="width: 12px; height:50px"></div>

Spritelar farklı boyutlarda background-sizeise, sprite genişliği% 100 olacak şekilde her sprite için a değerini yüzde olarak ayarlamanız gerekir.

Başka bir deyişle, görüntü 640 piksel genişliğinde ve bu resmin içindeki hareketli grafik 45 piksel genişliğinde ise, 45 pikselin 640 piksel olmasını sağlamak için

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

Sonra ofseti ayarlamanız gerekir. Ofsetin karmaşıklığı,% 0'ın sola ve% 100'ünün sağa hizalanmasıdır.

resim açıklamasını buraya girin

Bir grafik programcısı olarak,% 100'lük bir sapma, arka planı% 100'ü öğe boyunca, diğer bir deyişle tamamen sağ tarafa taşımak için beklerim, ancak% 100 ile kullanıldığında bunun anlamı yoktur backgrouhnd-position. background-position: 100%;sağa hizalanmış anlamına gelir. Yani, ölçeklemeden sonra bunu dikkate alan forumla

xOffsetScale = 1 + 1 / (xScale - 1)              
xOffset = offsetX * offsetScale / imageWidth

Ofsetin 31 piksel olduğunu varsayın

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

İşte 2 sprite ile 640x480 görüntü.

  1. 31x27y boyutunda 45w 32h
  2. 500x 370y boyutunda 105w 65h

resim açıklamasını buraya girin

Sprite için yukarıdaki matematik 1

xScale = imageWidth / spriteWidth
xScale = 640 / 45
xScale = 14.2222222222
xPercent = xScale * 100
xPercent = 1422.22222222%

xOffsetScale = 1 + 1 / (14.222222222 - 1)
xOffsetScale = 1.0756302521021115
xOffset = offsetX * xOffsetScale / imageWidth
xOffset = 31 * 1.0756302521021115 / 640
xOffset = 0.05210084033619603
xOffsetPercent = 5.210084033619603

yScale = imageHeight / spriteHEight
yScale = 480 / 32
yScale = 15
yPercent = yScale * 100
yPercent = 1500%

yOffsetScale = 1 + 1 / (15 - 1)
yOffsetScale = 1.0714285714285714
yOffset = offsetY * yOffsetScale / imageHeight
yOffset = 27 * 1.0714285714285714 / 480
yOffset = 0.06026785714285714
yOffsetPercent = 6.026785714285714

div {
  margin: 3px;
  display: inline-block;
}
.sprite {
  background-image: url('https://i.stack.imgur.com/mv9lJ.png');
}
.s1 {
  background-size:      1422.2222% 1500%;
  background-position:  5.210084033619603% 6.026785714285714%;
}
.s2 {
  background-size:      609.5238095238095% 738.4615384615385%;
  background-position:  93.45794392523367% 89.1566265060241%;
}
<div class="sprite s1" style="width: 45px; height:20px"></div>
<div class="sprite s1" style="width: 128px; height:30px"></div>
<div class="sprite s1" style="width: 64px; height:56px"></div>
<div class="sprite s1" style="width: 57px; height:60px"></div>
<div class="sprite s1" style="width: 45px; height:45px"></div>
<div class="sprite s1" style="width: 12px; height:50px"></div>
<div class="sprite s1" style="width: 50px; height:40px"></div>
<hr/>
<div class="sprite s2" style="width: 45px; height:20px"></div>
<div class="sprite s2" style="width: 128px; height:30px"></div>
<div class="sprite s2" style="width: 64px; height:56px"></div>
<div class="sprite s2" style="width: 57px; height:60px"></div>
<div class="sprite s2" style="width: 45px; height:45px"></div>
<div class="sprite s2" style="width: 12px; height:50px"></div>
<div class="sprite s2" style="width: 50px; height:40px"></div>


OffsetX ve offsetY değerlerini nasıl hesapladınız?
TryHarder

5

Eski yazı, ama işte kullandığım şey background-size:cover;(@Ceylan Pamir'e şapka ucu) ...

ÖRNEK KULLANIM
Yatay daire flipper (ön taraftaki fareyle üzerine gelin, farklı görüntü ile arkaya döndürür).

ÖRNEK
SPRİT 480 piksel x 240 piksel

ÖRNEK NİHAİ BOYUT
Tek görüntü @ 120px x 120px

GENEL KOD
.front {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:0px 0px;}

.back {width:120px; height:120px; background:url(http://www.example.com/images/image_240x240.png); background-size:cover; background-repeat:no-repeat; background-position:-120px 0px;}

KISALTILMIŞ VAKA FIDDLE
http://jsfiddle.net/zuhloobie/133esq63/2/


4

arka plan boyutunu kullanmayı deneyin: http://webdesign.about.com/od/styleproperties/p/blspbgsize.htm

ilk etapta görüntüleri istediğiniz boyutta oluşturmanızı engelleyen bir şey var mı?


Bunu çözmek için JavaScript ve CSS'yi birlikte kullanabilir miyim? Arka plan boyutunu denedim; Emlak. Çalıştıramıyorum. Görüntüyü herhangi bir nedenle ölçeklendirmez.
michael

1
background-sizeCSS 3'tür ve henüz yaygın olarak desteklenmemektedir.
Janmoesen

4
Şimdi çoğu tarayıcı sürümü tarafından desteklenmektedir. Bu caniuse.com/#search=background-size
kiranvj

4

Memnun kaldığım bu soruna bir çözüm oluşturmak biraz zamanımı aldı:

Sorun:

  • Bir SVG sprite simgeleri - 80px x 3200px deyin

  • İçerik boyut seçicilerindeki her kullanımını (: önce /: sonra), kullanılan ebatlara göre her bir hareketli grafiğin ko-ords'larını yeniden tanımlamadan çeşitli boyutlarda çeşitli yerlerde ölçeklemek istiyoruz.

Böylece bu çözüm aynı sprite ko-ords'ını a <button>olarak <menuitem>ölçeklendirirken kullanmanıza izin verir .

[data-command]::before {
    content: '';
    position: absolute;
    background-image: url("images/sprite.svgz");
    background-repeat: no-repeat;
    background-size: cover;
}

button[data-command]::before {
  width: 32px;
  height: 32px;
}

menuitem[data-command]::before {
  width: 24px;
  height: 24px;
}

[data-command="cancel"]::before {
  background-position: 0% 35%;
}

[data-command="logoff"]::before {
  background-position: 0% 37.5%;
}

Burada başkaları tarafından önerildiği gibi arka plan boyutunda değil, arka plan konumunda yüzdeleri (2 ondalık basamağa kadar) kullanarak, yeniden tanımlamaya gerek kalmadan aynı simge bildirimini herhangi bir boyuta ölçeklendirebilirsiniz.

Y konumu yüzdesi, orijinal hareketli grafik yüksekliği / simge yüksekliğidir ve% olarak belirtilir - bizim durumumuzda burada 80 piksel * 100/3200 piksel == her hareketli grafik,% 2,5'lik bir y konumu ile temsil edilir.

Fareyle üzerine gelme / fareyle üzerine gelme durumlarınız varsa hareketli grafiğin genişliğini iki katına çıkarabilir ve x konumu koordinatında belirtebilirsiniz.

Bu yaklaşımın dezavantajı, daha sonraki bir tarihte daha fazla simge eklemenin hareketli grafik yüksekliğini ve dolayısıyla% y-konumunu değiştireceğidir, ancak bunu yapmazsanız hareketli grafik koordinatlarınızın ihtiyacınız olan her ölçekli çözünürlük için değiştirilmesi gerekecektir.


2

Sanırım görüntüleri ölçeklemek için daha basit bir çözüm buldum: örnek - kullanmak istediğiniz 3 eşit boyutlu sprite içeren bir görüntü olduğunu varsayalım, görüntüyü ölçeklemek için CSS kullanın

background-size : 300% 100%;

ve ardından html öğenize uygulanması gereken özel yüksekliği ve genişliği belirtin, örn:

 width :45%;
 height:100px;

Örnek bir kod şöyle görünecektir:

.customclass {
    background: url("/sample/whatever.png") 0 0 no-repeat ;
    background-size : 300% 100%;
    width :45%;
    height:100px;
}

im css için oldukça yeni ve stil benim en iyi alan bu yapmak için yanlış bir yol olabilir .. ama Firefox / Chrome / Explorer 10 benim için çalıştı, umarım eski sürümlerinde de çalışır ..


2

Ölçeklemedeki boş alanı telafi etmek transform: scale(...);için eşleme kullanın ve ekleyin margin: -...px. ( * {outline: 1px solid}öğe sınırlarını görmek için kullanabilirsiniz ).


2

2018 burada. Yüzde ile arka plan boyutu kullanın.

SAC:

Bu, tek bir sprite sırasını varsayar. Sayfanızın genişliği, bir hareketli grafiğin 100 + genişliğine eşit olarak bölünebilen bir sayı olmalıdır . 108x108 piksel boyutunda 30 spriteınız varsa, son genişliği 5508px (50 * 108 + 108) yapmak için sonuna ekstra boşluk ekleyin.

CSS:

.icon{
    height: 30px;  /* Set this to anything. It will scale. */
    width: 30px; /* Match height. This assumes square sprites. */
    background:url(<mysheeturl>);
    background-size: 5100% 100%; /*  5100% because 51 sprites. */
}

/* Each image increases by 2% because we used 50+1 sprites. 
   If we had used 20+1 sprites then % increase would be 5%. */

.first_image{
    background-position: 0% 0;
}

.ninth_image{
    background-position: 16% 0; /* (9-1) x 2 = 16 */
}

HTML:

<div class ="icon first_image"></div>
<div class ="icon ninth_image"></div>


0

Hareketli grafik görüntüsünün sarmalayıcı öğesinin genişliğini ve yüksekliğini ayarlayın. Bu css kullanın.

{
    background-size: cover;
}

1
Bunun neden aşağı oylandığını anlamıyorum. Benim için çalıştı. Yöntemimi cevap olarak göndereceğim.
chris

Burada chris ile hemfikirim. Bu benim durumumda da sorunu çözüyor. Neden indirildiğinden emin değilim!
ShellZero

3
Sprite ile çalışmaz (soru başlığına bakın), bu yüzden bu çözüm aşağı indirildi.
Dimko Desu

-8

Kolay ... Hareketli görüntünün sayfasında farklı ölçeklerde aynı görüntünün iki kopyasını kullanmak. Uygulamanın mantığında Koordinatörleri ve boyutu ayarlayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.