chore: 调整 image 和 carousel (#2412)

* chore: 调整 image 和 carousel

1. image 扩充源码模式
2. carousel 扩充图片裁剪模式 cover | contain

* 更新 snapshot

* 补充样式
This commit is contained in:
liaoxuezhi 2021-08-19 15:06:29 +08:00 committed by GitHub
parent 6498c394b7
commit 0fae923b93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 279 additions and 160 deletions

View File

@ -12,62 +12,45 @@ exports[`Renderer:carousel 1`] = `
<div
class="cxd-Carousel-item fade in"
>
<span
class="cxd-TplField"
<div
class="cxd-Image cxd-Image--original cxd-Carousel-image"
>
<span>
<div
class="image "
style="background-image: url('https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png'); background-size: contain; background-repeat: no-repeat; background-position: center center;"
class="cxd-Image-origin cxd-Image-origin--contain"
>
<img
class="cxd-Image-image"
src="https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
/>
</div>
<div
class="title block"
class="cxd-Image-info"
>
<div
class="cxd-Image-title"
title="标题"
>
标题
</div>
<div
class="description block"
>
描述
</div>
</span>
</span>
</div>
</div>
<div
class="cxd-Carousel-item fade out"
>
<span
class="cxd-TplField"
>
<span>
<div
class="image "
style="background-image: url('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3893101144,2877209892&fm=23&gp=0.jpg'); background-size: contain; background-repeat: no-repeat; background-position: center center;"
class="cxd-Image cxd-Image--original cxd-Carousel-image"
>
<div
class="cxd-Image-origin cxd-Image-origin--contain"
>
<img
class="cxd-Image-image"
src="https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3893101144,2877209892&fm=23&gp=0.jpg"
/>
</span>
</span>
</div>
</div>
</div>
</div>
<div
class="cxd-Carousel-dotsControl"
@ -104,5 +87,4 @@ exports[`Renderer:carousel 1`] = `
</div>
</div>
</div>
</div>
`;

View File

@ -3,10 +3,10 @@
exports[`Renderer:image 1`] = `
<div>
<div
class="cxd-ImageField show"
class="cxd-ImageField cxd-ImageField--thumb show"
>
<div
class="cxd-Image"
class="cxd-Image cxd-Image--thumb"
>
<div
class="cxd-Image-thumbWrap"
@ -15,7 +15,7 @@ exports[`Renderer:image 1`] = `
class="cxd-Image-thumb cxd-Image-thumb--contain cxd-Image-thumb--1-1"
>
<img
class="b"
class="cxd-Image-image b"
src="https://www.baidu.com/img/bd_logo1.png"
/>
</div>

View File

@ -13,6 +13,10 @@ order: 33
```schema: scope="body"
{
"type": "carousel",
"auto": false,
"thumbMode": "cover",
"animation": "slide",
"height": 300,
"options": [
{
"image": "https://internal-amis-res.cdn.bcebos.com/images/2019-12/1577157239810/da6376bf988c.png"
@ -21,6 +25,7 @@ order: 33
"html": "<div style=\"width: 100%; height: 300px; background: #e3e3e3; text-align: center; line-height: 300px;\">carousel data</div>"
},
{
"thumbMode": "contain",
"image": "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3893101144,2877209892&fm=23&gp=0.jpg"
}
]
@ -75,7 +80,7 @@ itemSchema: {
## 属性表
| 属性名 | 类型 | 默认值 | 说明 |
| ---------------------------- | --------- | -------------------- | ------------------------------------------------------- |
| ---------------------------- | --------- | ---------------------- | ------------------------------------------------------- |
| type | `string` | `"carousel"` | 指定为 Carousel 渲染器 |
| className | `string` | `"panel-default"` | 外层 Dom 的类名 |
| options | `array` | `[]` | 轮播面板数据 |
@ -95,6 +100,7 @@ itemSchema: {
| controls | `array` | `['dots', 'arrows']` | 显示左右箭头、底部圆点索引 |
| controlsTheme | `string` | `light` | 左右箭头、底部圆点索引颜色,默认`light`,另有`dark`模式 |
| animation | `string` | fade | 切换动画效果,默认`fade`,另有`slide`模式 |
| thumbMode | `string` | `"cover" \| "contain"` | 图片默认缩放模式 |
- `type` 请设置成 `carousel`
- `className` 外层 Dom 的类名
@ -116,3 +122,4 @@ itemSchema: {
- `controls` 显示左右箭头、底部圆点索引,默认`['dots', 'arrows']`
- `controlsTheme` 左右箭头、底部圆点索引颜色,默认`light`,另有`dark`模式
- `animation` 切换动画效果,默认`fade`,另有`slide`模式
- `thumbMode` 图片默认缩放模式,可以配置 `"cover" | "contain"`

View File

@ -104,20 +104,23 @@ order: 52
"type": "static-image",
"name": "image",
"label": "1比1",
"thumbRatio": "1:1"
"thumbRatio": "1:1",
"thumbMode": "cover"
},
{
"type": "static-image",
"name": "image",
"label": "4比3",
"thumbRatio": "4:3"
"thumbRatio": "4:3",
"thumbMode": "cover"
},
{
"type": "static-image",
"name": "image",
"label": "颜色",
"label": "16比9",
"thumbRatio": "16:9"
"thumbRatio": "16:9",
"thumbMode": "cover"
}
]
}
@ -179,7 +182,29 @@ order: 52
"type": "image",
"width": "200px",
"height": "200px",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_216,l_1,f_jpg,q_80"
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg@s_0,w_400,l_1,f_jpg,q_80"
}
}
```
## 原图模式
> since 1.2.3
默认图片为缩略图模式,可以通过配置 imageMode: "original" 修改为原图模式,原图模式为块状展示,宽度尽可能占满。
```schema
{
"type": "page",
"data": {
"imageUrl": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg"
},
"body": {
"type": "image",
"imageMode": "original",
"name": "imageUrl",
"title": "这是标题",
"imageCaption": "这是一段说明"
}
}
```
@ -265,3 +290,4 @@ List 的内容、Card 卡片的内容配置同上
| enlargeCaption | `string` | | 放大预览的描述 |
| thumbMode | `string` | `contain` | 预览图模式,可选:`'w-full'`, `'h-full'`, `'contain'`, `'cover'` |
| thumbRatio | `string` | `1:1` | 预览图比例,可选:`'1:1'`, `'4:3'`, `'16:9'` |
| imageMode | `string` | `thumb` | 图片展示模式,可选:`'thumb'`, `'original'` 即:缩略图模式 或者 原图模式 |

View File

@ -176,25 +176,25 @@ Array<{
},
{
"image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg@s_0,w_216,l_1,f_jpg,q_80",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692942/d8e4992057f9.jpeg",
"a": "aaa2",
"b": "bbb2"
},
{
"image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg@s_0,w_216,l_1,f_jpg,q_80",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693148/1314a2a3d3f6.jpeg",
"a": "aaa3",
"b": "bbb3"
},
{
"image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg@s_0,w_216,l_1,f_jpg,q_80",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693379/8f2e79f82be0.jpeg",
"a": "aaa4",
"b": "bbb4"
},
{
"image": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg@s_0,w_216,l_1,f_jpg,q_80",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395692722/4f3cb4202335.jpeg",
"src": "https://internal-amis-res.cdn.bcebos.com/images/2020-1/1578395693566/552b175ef11d.jpeg",
"a": "aaa5",
"b": "bbb5"
}

View File

@ -58,16 +58,20 @@
}
&-container {
position: relative;
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
.#{$ns}Carousel-item {
width: 100%;
height: 100%;
position: absolute;
transition: ease-out all var(--Carousel-transitionDuration);
left: 0;
top: 0;
transition-duration: var(--Carousel-transitionDuration);
transition-timing-function: ease-out;
transition-property: transform, opacity;
&.fade {
opacity: 0;
@ -125,6 +129,16 @@
}
}
&-image {
width: 100%;
height: 100%;
}
&-image .#{$ns}Image-origin {
height: 100%;
width: 100%;
}
&-dotsControl {
position: absolute;
bottom: 0px;
@ -150,7 +164,9 @@
&-arrowsControl {
position: absolute;
width: 100%;
height: inherit;
height: 100%;
top: 0;
left: 0;
z-index: 100;
text-align: center;

View File

@ -10,14 +10,28 @@
}
.#{$ns}Image {
display: inline-block;
border: var(--borderWidth) solid var(--borderColor);
&--thumb {
display: inline-block;
padding: var(--gap-xs);
}
&-thumbWrap {
position: relative;
}
&-image {
display: block;
}
&--original &-image {
max-width: 100%;
max-height: 100%;
width: auto;
margin: auto;
}
&-thumb {
width: px2rem(110px);
height: px2rem(110px);
@ -36,7 +50,12 @@
}
&-info {
padding: 5px 10px;
}
&--thumb &-info {
width: px2rem(110px);
padding: 0;
}
&-thumb--4-3 {
@ -80,6 +99,12 @@
left: 0;
object-fit: contain;
}
&-origin--contain > img {
width: 100% !important;
height: 100% !important;
object-fit: contain;
}
}
@supports (object-fit: cover) {
@ -92,6 +117,12 @@
left: 0;
object-fit: cover;
}
&-origin--cover > img {
width: 100% !important;
height: 100% !important;
object-fit: cover;
}
}
&-caption {
@ -99,7 +130,8 @@
}
&-title {
font-size: var(--fontSizeSm);
font-size: var(--fontSizeBase);
color: var(--text--loud-color);
}
&-overlay {
@ -138,7 +170,7 @@
}
}
.#{$ns}ImageField {
.#{$ns}ImageField--thumb {
display: inline-block;
position: relative;
@include clearfix();

View File

@ -15,6 +15,8 @@ import {
} from '../utils/helper';
import {Icon} from '../components/icons';
import {BaseSchema, SchemaCollection, SchemaName, SchemaTpl} from '../Schema';
import Html from '../components/Html';
import Image from '../renderers/Image';
/**
* Carousel
@ -75,6 +77,11 @@ export interface CarouselSchema extends BaseSchema {
name?: SchemaName;
/**
*
*/
thumbMode?: 'contain' | 'cover';
/**
*
*/
@ -102,24 +109,32 @@ export interface CarouselState {
}
const defaultSchema = {
type: 'tpl',
tpl: `
<% if (data.hasOwnProperty('image')) { %>
<div style="background-image: url('<%= data.image %>'); background-size: contain; background-repeat: no-repeat; background-position: center center;" class="image <%= data.imageClassName %>"></div>
<% if (data.hasOwnProperty('title')) { %>
<div class="title <%= data.titleClassName %>"><%= data.title %></div>
<% } %>
<% if (data.hasOwnProperty('description')) { %>
<div class="description <%= data.descriptionClassName %>"><%= data.description %></div>
<% } %>
<% } else if (data.hasOwnProperty('html')) { %>
<%= data.html %>
<% } else if (data.hasOwnProperty('item')) { %>
<%= data.item %>
<% } else { %>
<%= '未找到渲染数据' %>
<% } %>
`
component: (props: any) => {
const data = props.data || {};
const thumbMode = props.thumbMode;
const cx = props.classnames;
return (
<>
{data.hasOwnProperty('image') ? (
<Image
src={data.image}
title={data.title}
imageCaption={data.description}
thumbMode={data.thumbMode ?? thumbMode ?? 'contain'}
imageMode="original"
className={cx('Carousel-image')}
/>
) : data.hasOwnProperty('html') ? (
<Html html={data.html} />
) : data.hasOwnProperty('item') ? (
<span>{data.item}</span>
) : (
<p></p>
)}
</>
);
}
};
export class Carousel extends React.Component<CarouselProps, CarouselState> {
@ -370,8 +385,9 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
>
{render(
`${current}/body`,
itemSchema ? itemSchema : defaultSchema,
itemSchema ? itemSchema : (defaultSchema as any),
{
thumbMode: this.props.thumbMode,
data: createObject(
data,
isObject(option)
@ -385,8 +401,6 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
}}
</Transition>
))}
{dots ? this.renderDots() : null}
{arrows ? this.renderArrows() : null}
</div>
);
}
@ -397,6 +411,9 @@ export class Carousel extends React.Component<CarouselProps, CarouselState> {
style={carouselStyles}
>
{body ? body : placeholder}
{dots ? this.renderDots() : null}
{arrows ? this.renderArrows() : null}
</div>
);
}

View File

@ -56,7 +56,7 @@ export interface ImageSchema extends BaseSchema {
/**
*
*/
showDimensions?: boolean;
// showDimensions?: boolean;
/**
*
@ -90,6 +90,11 @@ export interface ImageSchema extends BaseSchema {
caption?: SchemaTpl;
/**
*
*/
imageMode?: 'thumb' | 'original';
/**
*
*/
@ -135,24 +140,49 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
onLoad,
enlargeAble,
translate: __,
overlays
overlays,
imageMode
} = this.props;
return (
<div className={cx('Image', className)}>
<div
className={cx(
'Image',
imageMode === 'original' ? 'Image--original' : 'Image--thumb',
className
)}
>
{imageMode === 'original' ? (
<div
className={cx(
'Image-origin',
thumbMode ? `Image-origin--${thumbMode}` : ''
)}
style={{height: height, width: width}}
>
<img
onLoad={onLoad}
className={cx('Image-image', imageClassName)}
src={src}
alt={alt}
/>
</div>
) : (
<div className={cx('Image-thumbWrap')}>
<div
className={cx(
'Image-thumb',
thumbClassName,
thumbMode ? `Image-thumb--${thumbMode}` : '',
thumbRatio ? `Image-thumb--${thumbRatio.replace(/:/g, '-')}` : ''
thumbRatio
? `Image-thumb--${thumbRatio.replace(/:/g, '-')}`
: ''
)}
style={{height: height, width: width}}
>
<img
onLoad={onLoad}
className={cx(imageClassName)}
className={cx('Image-image', imageClassName)}
src={src}
alt={alt}
/>
@ -173,6 +203,8 @@ export class ImageThumb extends React.Component<ImageThumbProps> {
</div>
) : null}
</div>
)}
{title || caption ? (
<div key="caption" className={cx('Image-info')}>
{title ? (
@ -204,6 +236,7 @@ export interface ImageFieldProps extends RendererProps {
description?: string;
enlargeTitle?: string;
enlargeCaption?: string;
imageMode?: 'thumb' | 'original';
thumbMode: 'w-full' | 'h-full' | 'contain' | 'cover';
thumbRatio: '1:1' | '4:3' | '16:9';
originalSrc?: string; // 原图
@ -219,7 +252,6 @@ export interface ImageFieldProps extends RendererProps {
},
target: any
) => void;
showDimensions?: boolean;
}
export class ImageField extends React.Component<ImageFieldProps, object> {
@ -276,8 +308,7 @@ export class ImageField extends React.Component<ImageFieldProps, object> {
placeholder,
originalSrc,
enlargeAble,
showDimensions,
name
imageMode
} = this.props;
const finnalSrc = src ? filter(src, data, '| raw') : '';
@ -285,7 +316,15 @@ export class ImageField extends React.Component<ImageFieldProps, object> {
finnalSrc || getPropValue(this.props) || defaultImage || imagePlaceholder;
return (
<div className={cx('ImageField', className)}>
<div
className={cx(
'ImageField',
imageMode === 'original'
? 'ImageField--original'
: 'ImageField--thumb',
className
)}
>
{value ? (
<ThemedImageThumb
imageClassName={imageClassName}
@ -297,10 +336,10 @@ export class ImageField extends React.Component<ImageFieldProps, object> {
caption={filter(imageCaption, data)}
thumbMode={thumbMode}
thumbRatio={thumbRatio}
originalSrc={filter(originalSrc, data, '| raw')}
originalSrc={filter(originalSrc, data, '| raw') ?? value}
enlargeAble={enlargeAble && value !== defaultImage}
onEnlarge={this.handleEnlarge}
showDimensions={showDimensions}
imageMode={imageMode}
/>
) : (
<span className="text-muted">{placeholder}</span>