dioxus-compose 가이드

이미지와 배경

이미지가 무엇인지는 앱이 정합니다

dioxus-compose 는 아무것도 내려받지 않습니다. <img src> 와 CSS url() 은 쓴 그대로 기록되고, 앱이 넘기는 이미지 리졸버가 크기와 그릴 에셋을 알려 줍니다. 그라디언트는 CSS 만으로 계산되므로 리졸버가 필요 없습니다.

이미지 리졸버

앱은 이미지를 이미 메모리에 갖고 있을 수도, 직접 내려받고 싶을 수도, 일부는 거부하고 싶을 수도 있습니다. 그래서 읽어 오는 것은 앱이 정하고, 그 통로는 트레이트 하나입니다.

dioxus_compose::html
pub trait ImageResolver {
    /// The asset that draws the image at `url`, or None to draw nothing.
    /// Asked while a plan is built, never during layout.
    fn resolve(&mut self, url: &str) -> Option<AssetId>;

    /// The natural size, when the app knows it without fetching anything.
    /// Asked during layout. None, the default, leaves the image without one.
    fn size(&mut self, _url: &str) -> Option<ImageSize> {
        None
    }
}

AssetId 는 렌더러에 등록한 이미지에 앱이 붙인 번호입니다. 계획에 그대로 돌려줄 뿐 안을 들여다보지 않습니다. ImageSize 는 CSS 픽셀 단위이므로, CSS 픽셀당 장치 픽셀이 2 인 화면용 이미지는 여기서 픽셀 크기의 절반입니다.

리졸버는 HtmlConfig::images 에 넣거나, 나중에 HtmlDom::set_image_resolver 로 넣습니다. 리졸버가 없으면 <img> 는 속성과 CSS 가 준 크기만 갖고, 어떤 이미지도 그려지지 않습니다.

samples/support/src/lib.rs, 줄임: 정해진 목록을 아는 리졸버
impl ImageResolver for Images {
    fn resolve(&mut self, url: &str) -> Option<AssetId> {
        self.find(url).map(|(_, _, asset)| *asset)
    }

    fn size(&mut self, url: &str) -> Option<ImageSize> {
        self.find(url).map(|(_, size, _)| *size)
    }
}

URL

HtmlConfig::base_url 은 상대 src 와 CSS url() 의 기준입니다. 없거나, data: URL 처럼 아무것도 그 기준으로 풀 수 없는 값이면, 상대 URL 은 쓴 그대로 리졸버에 갑니다. photos/tram.jpg 는 photos/tram.jpg 그대로입니다.

img 요소

자체 크기가 없는 <img> 는 리졸버가 준 크기로 배치됩니다. 상자 안 어디에 그림을 그릴지는 object-fit 이 정합니다. samples/gallery 에서 48 x 48 아바타는 본래 크기를 지키고, 사진은 타일을 cover 로 채우고, 경로 지도는 contain 으로 전체가 보입니다.

samples/gallery/src/lib.rs
.avatar { border-radius: 50%; }

.tile {
    margin: 0;
    border-radius: 8px;
    overflow: hidden;
}

.tile img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.tile img.whole { object-fit: contain; }

배경 이미지

background-image 층은 CSS 순서를 지킵니다. 첫 층이 맨 위에 그려지고, 모든 층이 배경색 위에 그려집니다. background-size(cover, contain, 길이), background-position, background-repeat 는 사각형으로 풀려 있으므로, 렌더러는 CSS 를 해석하지 않고 상자 안에 이미지를 그리기만 합니다.

samples/gallery/src/lib.rs
.postcard {
    background-image: url(textures/postcard.png);
    background-size: cover;
    background-position: center;
}

그라디언트

linear-gradient(), radial-gradient() 와 그 반복형은 채울 타일을 기준으로 풀립니다. to right 같은 키워드는 그 타일 크기에서 뜻하는 각도가 되고, 색 정지점마다 위치와 색이 정해집니다. gallery 의 헤더는 그라디언트 하나입니다.

samples/gallery/src/lib.rs
.hero {
    display: flex;
    align-items: center;
    gap: 16px;
    height: 160px;
    padding: 0 32px;
    background-image: linear-gradient(to right, #4f46e5, #06b6d4);
    color: #ffffff;
}

정지점 하나의 색을 바꾸면 배경색을 바꿀 때처럼 계획에서 바뀌는 것은 하나입니다.

아직 없는 것