【问题标题】:React Native HTML - rendering a linear background gradientReact Native HTML - 呈现线性背景渐变
【发布时间】:2021-11-10 09:45:49
【问题描述】:

我目前的 HTML 溢出高度:300 一盒,其中使用了 React Native HTML。 (这个包:https://www.npmjs.com/package/react-native-render-html

这会在“溢出”时提供以下输出 - 在“阅读更多”链接之前略微锐利地截断文本。

我试图用这个库实现的,是在盒子的最后一个元素上从透明到白色的线性渐变。一个绝对定位,底部 0:渐变,给人一种有更多可看性的错觉,并且没有那么刺耳的截断。

在我下面的代码中:<scrollfade> test </scrollfade> 是我试图通过它实现的元素。

您会注意到这里定义了它的自定义渲染器:

scrollfade: HTMLElementModel.fromCustomModel({
      tagName: 'scrollfade',
      mixedUAStyles: {
        position: 'absolute',
        width: '100%',
        height: '220px',
        left: 0,
        bottom: 0,
        display: 'flex',
      },
      contentModel: HTMLContentModel.block,
    }),

然而,这似乎不利于 backgroundImages、背景渐变等能够定义可能实现这一目标的样式。我尝试使用 from 'react-native-linear-gradient' - 就在 html 渲染器下方,但它不在 dom 中的正确位置内产生任何影响。即文本严厉地切断,然后渐变显示。我不确定是否可以混合这两种技术并在 html 模板中以某种方式使用本机组件,我怀疑不是。关于如何编写自定义渲染器的想法?用于渐变并在模板中定义它,或者欢迎使用其他更简单的方法。

为了澄清,我正在寻找一种视觉渐变解决方案,该解决方案允许文本预溢出略微闪耀。

import React, { FunctionComponent } from 'react';
import { StyleSheet, Text, useWindowDimensions, ViewStyle } from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import RenderHtml, {
  defaultSystemFonts,
  HTMLContentModel,
  HTMLElementModel,
  MixedStyleRecord,
} from 'react-native-render-html';
import { Theme, useTheme } from '../styles/native';

interface Props {
  html: string;
  padding: boolean;
  scrollEnabled: boolean;
  style?: ViewStyle;
  pointerEvents?: 'none' | 'auto' | 'box-none' | 'box-only';
}

// Later on in your styles..
const styles = StyleSheet.create({
  linearGradient: {
    flex: 1,
    height: 100,
  },
});

const tagsStyles: MixedStyleRecord = (theme: Theme) => {
  return {
    body: {
      color: theme.textMid,
      fontFamily: 'OpenSans-Regular',
      background: theme.background,
      overflow: 'hidden',
    },
    a: {
      color: theme.primary,
    },
    h1: {
      color: theme.textDark,
    },
    h2: {
      color: theme.textDark,
    },
    h3: {
      color: theme.textDark,
    },
    h4: {
      color: theme.textDark,
    },
    h5: {
      color: theme.textDark,
    },
    h6: {
      color: theme.textDark,
    },
  };
};

const customHTMLElementModels = (style: any, scrollEnabled: boolean, theme: Theme, padding: boolean) => {
  return {
    template: HTMLElementModel.fromCustomModel({
      tagName: 'template',
      mixedUAStyles: {
        ...style,
        position: 'relative',
        padding: padding ? '0 20px 40px 20px' : '0',
        overflow: scrollEnabled ? 'scroll' : 'hidden',
      },
      contentModel: HTMLContentModel.block,
    }),
    scrollfade: HTMLElementModel.fromCustomModel({
      tagName: 'scrollfade',
      mixedUAStyles: {
        position: 'absolute',
        width: '100%',
        height: '220px',
        left: 0,
        bottom: 0,
        display: 'flex',
      },
      contentModel: HTMLContentModel.block,
    }),
  };
};

const wrapHTMLInBody = (html: string) => {
  return `
      <body>
          <template>
            ${html}
            <scrollfade>test</scrollfade>
          </template>
          
      </body>
  `;
};

const Description: FunctionComponent<Props> = (props) => {
  const { width } = useWindowDimensions();
  const theme = useTheme();
  const systemFonts = [...defaultSystemFonts, 'OpenSans-Regular'];
  const endColor = getTheme() === 'dark' ? 'rgba(0,0,0,0)' : 'rgba(255,255,255,0)';

  return (
    <>
      <RenderHtml
        contentWidth={width}
        source={{
          html: wrapHTMLInBody(
            '<p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p>',
          ),
        }}
        tagsStyles={tagsStyles(theme)}
        customHTMLElementModels={customHTMLElementModels(props.style, props.scrollEnabled, theme, props.padding)}
        systemFonts={systemFonts}
      />
    </>
  );
};

export default Description;

【问题讨论】:

    标签: html react-native react-native-render-html


    【解决方案1】:

    我认为您需要的是component custom renderer

    您可以为一个 html 标签定义自定义模型和自定义(组件)渲染器。这方面的一些东西:

    import React, {FunctionComponent} from 'react';
    import {StyleSheet, Text, useWindowDimensions, ViewStyle} from 'react-native';
    import LinearGradient from 'react-native-linear-gradient';
    import RenderHtml, {
      CustomRendererProps,
      defaultSystemFonts,
      HTMLContentModel,
      HTMLElementModel,
      MixedStyleRecord,
      RenderHTMLProps,
      TChildrenRenderer,
      TBlock,
      TNodeChildrenRenderer,
    } from 'react-native-render-html';
    import {Theme, useTheme} from '../styles/native';
    
    interface Props {
      html: string;
      padding: boolean;
      scrollEnabled: boolean;
      style?: ViewStyle;
      pointerEvents?: 'none' | 'auto' | 'box-none' | 'box-only';
    }
    
    // Later on in your styles..
    const styles = StyleSheet.create({
      linearGradient: {
        flex: 1,
        height: 100,
      },
    });
    
    const customHTMLElementModels = (
      style: any,
      scrollEnabled: boolean,
      theme: Theme,
      padding: boolean,
    ) => {
      return {
        template: HTMLElementModel.fromCustomModel({
          tagName: 'template',
          mixedUAStyles: {
            ...style,
            position: 'relative',
            padding: padding ? '0 20px 40px 20px' : '0',
            overflow: scrollEnabled ? 'scroll' : 'hidden',
          },
          contentModel: HTMLContentModel.block,
        }),
        scrollfade: HTMLElementModel.fromCustomModel({
          tagName: 'scrollfade',
          mixedUAStyles: {
            position: 'absolute',
            width: '100%',
            height: '220px',
            left: 0,
            bottom: 0,
            display: 'flex',
          },
          contentModel: HTMLContentModel.block,
        }),
      };
    };
    
    const renderers: RenderHTMLProps['renderers'] = {
      scrollfade: ({TDefaultRenderer, ...props}: CustomRendererProps<TBlock>) => {
        return (
          <TDefaultRenderer {...props}>
            <TNodeChildrenRenderer tnode={props.tnode} />
            <LinearGradient style={styles.linearGradient} />
          </TDefaultRenderer>
        );
      },
    };
    
    const wrapHTMLInBody = (html: string) => {
      return `
          <body>
              <template>
                ${html}
                <scrollfade>test</scrollfade>
              </template>
              
          </body>
      `;
    };
    
    const Description: FunctionComponent<Props> = (props) => {
      const {width} = useWindowDimensions();
      const theme = useTheme();
      const systemFonts = [...defaultSystemFonts, 'OpenSans-Regular'];
    
      return (
        <>
          <RenderHtml
            contentWidth={width}
            source={{
              html: wrapHTMLInBody(
                '<p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p><p>Miss polly had a dolly that was sick sick sick</p>',
              ),
            }}
            renderers={renderers}
            customHTMLElementModels={customHTMLElementModels(
              props.style,
              props.scrollEnabled,
              theme,
              props.padding,
            )}
            systemFonts={systemFonts}
          />
        </>
      );
    };
    
    export default Description;
    

    【讨论】:

      猜你喜欢
      • 2019-02-01
      • 2019-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多