2013-02-17 16 views
9

Non sono sicuro che sia possibile o meno, ma è possibile utilizzare le tecniche CSS/Jquery per creare una trama sfumata? Qualcosa di simile a questo enter image description hereCreazione di una mesh con gradiente in CSS/Jquery

Mi piacerebbe generare in modo casuale questa trama e quindi eventualmente animarla, quindi sto cercando di evitare l'uso di immagini. Non sono sicuro che qualcosa del genere sarebbe possibile.

Stavo pensando di creare diversi livelli di singoli gradienti e quindi di sovrapporli tutti insieme in una posizione fissa e modificare le impostazioni di opacità?

+0

+1 per l'immagine utile sopra –

risposta

3

attualmente

Ho sperimentato qualcosa del genere alcuni anni fa, utilizzando SVG, il tag canvas HTML5 e più recentemente i gradienti CSS3. Non credo che ci sia un modo naturale per andare oltre i semplici gradienti lineari o radiali al momento.

La domanda è se un gradiente di mesh può essere simulato utilizzando solo semplici gradienti lineari e radiali (che sono gli unici strumenti disponibili).

Sfortunatamente, quando si combinano più gradienti usando opacità o rgba, i colori dei diversi gradienti tendono a combinarsi in un modo che non è utile, portando a colori sbiaditi. Evitare ciò richiederebbe la possibilità di renderlo nel browser come un singolo gradiente complesso.

Ci sono anche limitazioni significative alle forme che i gradienti possono avere: gradienti lineari ad un angolo arbitrario e gradienti ellittici con simmetria radiale. Né consente forme irregolari a forma libera.Le trasformazioni 2D che possono essere applicate all'immagine risultante sono di natura abbastanza regolare (ridimensionamento, inclinazione, ecc.).

In futuro

L'opzione più promettente io sappia per il prossimo futuro è il sostegno possibile per le sfumature di maglia in SVG 2.0 (e, forse, le curve di diffusione pure). Se ciò accade e alla fine è supportato dai browser, dovrebbe iniziare a espandere notevolmente le opzioni. E il tag canvas HTML5 e CSS3 potrebbero seguire poco dopo.

E come @vals ha sottolineato nel commento qui sotto, WebGL dovrebbe offrire alcune opzioni molto promettenti (per tag di tela HTML5 che utilizzano un contesto 3D).

Link correlati

+1

Hai ragione che nella sovrapposizione di più gradienti hai il problema della mancanza di controllo sulla funzione di media/composizione. È anche vero che dato un insieme abbastanza grande di gradienti, puoi approssimare con sufficiente accuratezza (nel limite, 1 gradiente per pixel ...) ma questo non è ovviamente pratico. Oltre alle possibilità che dici, c'è anche WebGL. Hai una vera interpolazione tra i vertici, e la libertà totale fiorisce la forma. – vals

+0

@vals: Grazie per le informazioni di background su WHY i gradienti non si sovrappongono bene; Avevo osservato questo, ma non potevo spiegarlo. Ho sperimentato con la rottura di una sfumatura in piccoli quadrati con un colore solido bg per ciascuno, ma rende estremamente lentamente e/o sembra bloccante. WebGL suona come una buona opzione a lungo termine! –

+0

Rileggendo il post, un piccolo dettaglio che mi manca la prima volta che l'ho letto. Parli di combinare le sfumature con l'opacità. Questo ha l'inconveniente che l'opacità è un singolo valore per tutto l'overlay.Specificare il gradiente come rgba ti dà un risultato migliore (ma ancora limitato), dato che puoi cambiare alpha a piacimento. – vals

4

Ho fatto un semplice layout per dimostrarlo.

Per prima cosa, inserirò 4 div, il primo a mostrare i risultati parziali e l'ultimo a vedere il risultato finale. La marcatura è semplicemente:

<div class="box mesh1"></div> 
<div class="box mesh2"></div> 
<div class="box mesh3"></div> 
<div class="box mesh"></div> 

qui scatola è solo per le dimensioni, mesh1 a 3 detengono i risultati parziali, in maglia mettiamo tutto insieme.

Il CSS è:

.box { 
    width: 400px; 
    height: 150px; 
    position: relative; 
    display: inline-block; 
} 

.mesh1, .mesh { 
background: 
    -webkit-linear-gradient(5deg, rgba(0, 250, 0, 0.5), rgba(0, 100, 0, 0.5)) 
} 

.mesh:after, .mesh:before { 
    content: ""; 
    position: absolute; 
    left: 0px; 
    bottom: 0px; 
    top: 0px; 
    right: 0px; 
} 
.mesh2, .mesh:after { 
background: -webkit-radial-gradient(center center, circle cover, rgba(250, 0, 0, 0.6) 0%, rgba(120, 0, 10, 0.5) 100%);} 

.mesh3, .mesh:before { 
background: -webkit-radial-gradient(10% 10%, ellipse cover, rgba(0, 0, 250, 0.6) 0%, white 100%);} 

sto dando alla classe mesh1 una bassa lineare, inclinate di 5 gradi, e specificando i colori in formato RGBA per consentire la trasparenza.

Quindi, per essere in grado di sovrapporre più gradienti, specifco per pseudo elementi come prima e dopo, condividendo le stesse proprietà di layout.

All'elemento successivo fornisco una sfumatura circolare, condivisa con la mesh2 All'elemento precedente attribuisco una sfumatura ellittica, decentrata. Tutti possono essere rgba.

Alla fine, si vede nella maglia div il risultato della sovrapposizione di tutto

(ho usato in tutto il mondo la notazione webkit per farla breve)

Non direi che è molto più artistica, ma lascio questa parte per voi :-)

fiddle here

+0

buon tentativo - problema da esso viene infangato up abbastanza veloce. +1. – Bosworth99

2

Nella mia prima risposta, ho interpretato questo andare più nel modo "artistico" che in modo "matematico". La risposta di Matt Coughlin mi fa pensare a una risposta più matematica, in cui renderemmo la parte "mesh" del requisito più rigorosa.

Cioè, abbiamo una matrice di colori e vogliamo mostrarlo in una griglia. Se la griglia ha una spaziatura di dire 100px, allora il colore [x] [y] della matrice verrebbe assegnato al pixel in 100x e 100y. I pixel in mezzo sarebbero calcolati in modo bilineare.

Per un tale approccio, il css sarebbe:

.mesh { overflow: hidden; position: absolute; width: 300px; height: 300px; } 

.tile { width: 200px; height: 200px; position: absolute; display: block; } 

.tile11, .tile21, .tile31 { 
left: -50px; 
} 
.tile12, .tile22, .tile32 { 
left: 50px; 
} 
.tile13, .tile23, .tile33 { 
left: 150px; 
} 
.tile11, .tile12, .tile13 { 
top: -50px; 
} 
.tile21, .tile22, .tile23 { 
    top: 50px; 
} 
.tile31, .tile32, .tile33 { 
top: 150px; 
} 

.tile11 { 
background: -webkit-radial-gradient(center center, 100px 100px, 
     rgba(255, 0, 0, 1) 0%, 
     rgba(255, 0, 0, 0.5) 50%, 
     rgba(255, 0, 0, 0) 100%);} 

.tile12 { 
background: -webkit-radial-gradient(center center, 100px 100px, 
     rgba(255, 0, 0, 1) 0%, 
     rgba(255, 0, 0, 0.5) 50%, 
     rgba(255, 0, 0, 0) 100%);} 

sto usando ogni div come un collaboratore locale della rete, ottenendo solo di "toccare" il vicino inmediate, e andare a una piena trasparenza oltre quel punto.

Il risultato è questo:

fiddle

I primi 2 colori sono entrambi rossi come test. In un sistema perfetto, la linea che collega i 2 punti dovrebbe essere sempre perfettamente rossa.

E 'vero che non è un risultato perfetto, ma il "confondere" o "washyness" del risultato è più o meno evitato