Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createAnimation 在iOS和Android两个平台表现不一致 #5261

Closed
darkfiredarkhalo opened this issue Jan 7, 2020 · 2 comments
Closed
Assignees
Labels
T-h5 Target - 编译到 H5 V-1 Version - 1.x

Comments

@darkfiredarkhalo
Copy link

问题描述

项目中有一个竖直的文字跑马灯效果,由于是评论数据,数据长度不定,无法预知数据可能的高度,所以没在css中实现,就使用了createAnimation,假定每条数据显示1秒,在数据变化时,重新计算时间(time),重新生成动画对象,重新开始动画,并在onTransitionend的时候重置动画,由此循环往复实现;问题是动画速度在Android上正常,在Chrome/Safari正常,,在iOS上却非常快,并且在荣耀10的自带浏览器中不起作用

复现步骤

  1. 复制以下代码新建组件;
  2. 新建页面,import新建的组件,并在页面中使用
  3. 动态给组件添加数据
/* eslint-disable react/jsx-key */
/**
 * 竖直跑马灯, 匀速
 * 
 * 使用方式一:
 *      <Marquee data={...}/>
 * 
 * 使用方式二:
 *      <Marquee>
 *          ....
 *      </Marquee>
 *      
 */
import Taro, { Component } from '@tarojs/taro';
import { View, Text, ScrollView } from '@tarojs/components';
import PropTypes from 'prop-types';

export default class Marquee extends Component {
    static propTypes = {
		duration: PropTypes.number, // 动画持续时长(毫秒),优先级低于interval
        width: PropTypes.oneOfType([PropTypes.string,PropTypes.number]),    // 跑马灯组件宽度
        height: PropTypes.oneOfType([PropTypes.string,PropTypes.number]),   // 跑马灯组件高度
        data: PropTypes.array,    // 数据
        interval: PropTypes.number,     // 每条数据的展示时长(毫秒),优先级高于duration
    };
    static defaultProps = {
        duration: 10000,
        width: '100%',
        height: '100%',
        data: [],
        interval: 1000,
    };
    state = {
        marqueeAnimate: '',
    };
    marqueeAnimation = null;
    rersetAnimation = null;
    contentHeight = 10;
    isEnd = false;
    componentWillMount(){
        const {
            duration,
            data,
            interval
        } = this.props;
        let time = duration;
        if(data && data.length>0){
            time = data.length * interval;
            this.contentHeight = data.length * 30
        }
        this.marqueeAnimation = Taro.createAnimation({
            duration: time, 
            timingFunction: 'linear',
            delay: 0,
            transformOrigin: '50% 50%',
        });
        this.rersetAnimation = Taro.createAnimation({
            duration: 10, 
            timingFunction: 'step-start',
            delay: 0,
            transformOrigin: '50% 50%',
        });
    };
    componentWillReceiveProps(nextProps) {
        const {
            interval
        } = this.props;
        const oldData = this.props.data
        const nextData = nextProps.data;
        if((!oldData && !!nextData) || (oldData && oldData.length || 0) !== (nextData && nextData.length || 0)){
            console.log('接收新数据数据>>>', {oldData, nextData});
            const time = nextData.length * interval;
            this.contentHeight = nextData.length * 30
            this.marqueeAnimation = Taro.createAnimation({
                duration: time, 
                timingFunction: 'linear',
                delay: 0,
                transformOrigin: '50% 50%',
            });
            this._resetAnimate();
        }
    };
    componentDidShow() {
        const {
            data,
        } = this.props;
        console.log('数据>>>', data);
        if(data && data.length>0){
            this._startAnimate();
        }else{
            const _this= this;
            const query = Taro.createSelectorQuery();
            query.select('#marqueeContent').boundingClientRect();
            query.exec((res)=>{
                console.log('测量结果>>>', res);
                const { height } = res[0];
                _this.contentHeight = height;
                _this._startAnimate();
            })
        }
    };
    _startAnimate = () => {
        this.isEnd = false
        console.log('动画开始>>>', this.contentHeight);
        const {
            height,
        } = this.props;
        this.marqueeAnimation.translateY(-this.contentHeight).step();
        this.setState({
            marqueeAnimate: this.marqueeAnimation.export(),
        })
    };
    _resetAnimate = (e) => {
        this.isEnd = true;
        console.log('动画重置>>>', e);
        const {
            height,
        } = this.props;
        this.rersetAnimation.translateY(0).step();
        this.setState({
            marqueeAnimate: this.rersetAnimation.export(),
        })
    };
    _animateEnd = () => {
        if(this.isEnd){
            this._startAnimate();
        }else{
            this._resetAnimate();
        }
    };
    _stopAnamite = (e) => {
        console.log('触摸开始>>>', e);
        if(this.isEnd){
            this.rersetAnimation.export();
        }else{
            this.marqueeAnimation.export();
        }
    };
    _resumeAnamite = (e) => {
        console.log('触摸结束>>>', e);
        // if(this.isEnd){
        //     this._startAnimate();
        // }else{
        //     this._resetAnimate();
        // }
    };
	render() {
        const {
            height,
            width,
            data,
            textStyle
        } = this.props;
        const {
            marqueeAnimate
        } = this.state;
        const widthValue = typeof(width)==='string' ? width : Taro.pxTransform(width);
        const heightValue = typeof(height)==='string' ? height : Taro.pxTransform(height);
        if(data && data.length>0){
            return (
                <View onTouchStart={this._stopAnamite} onTouchEnd={this._resumeAnamite} style={{ width: widthValue, height: heightValue,  overflow: 'hidden' }}>
                    <ScrollView id='marqueeContent' animation={marqueeAnimate} onTransitionend={this._animateEnd}>
                        <View style={{ display: 'flex', flexDirection: 'column', paddingTop: Taro.pxTransform(height) }}>
                            {data.map((item,index)=>{
                                return <Text taroKey={String(index)} style={textStyle}>{ item }</Text>
                            })}
                        </View>
                    </ScrollView>
                </View> 
            )  
        }
        return (
            <View style={{ width: widthValue, height: heightValue, overflow: 'hidden' }}>
                <ScrollView id='marqueeContent' animation={marqueeAnimate} onTransitionend={this._animateEnd}>
                    <View style={{ display: 'flex', flexDirection: 'column', paddingTop: Taro.pxTransform(height) }}>
                        { this.props.children }
                    </View>
                </ScrollView>
            </View> 
        )
	}
}

期望行为

createAnimation在各平台表现一致化,能兼容市场主流手机的默认浏览器,或者给出一个兼容性建议

报错信息

无报错

系统信息

Taro CLI 1.3.29 environment info:
    System:
      OS: macOS 10.15.2
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 13.5.0 - /usr/local/bin/node
      Yarn: 1.12.3 - /usr/local/bin/yarn
      npm: 6.13.4 - /usr/local/bin/npm
    npmPackages:
      @tarojs/async-await: ^2.0.0-beta.13 => 2.0.0-beta.13 
      @tarojs/cli: 1.3.31 => 1.3.31 
      @tarojs/components: 1.3.31 => 1.3.31 
      @tarojs/components-qa: 1.3.31 => 1.3.31 
      @tarojs/plugin-babel: 1.3.31 => 1.3.31 
      @tarojs/plugin-csso: 1.3.31 => 1.3.31 
      @tarojs/plugin-uglifyjs: 1.3.31 => 1.3.31 
      @tarojs/router: 1.3.31 => 1.3.31 
      @tarojs/taro: 1.3.31 => 1.3.31 
      @tarojs/taro-alipay: 1.3.31 => 1.3.31 
      @tarojs/taro-h5: 1.3.31 => 1.3.31 
      @tarojs/taro-qq: 1.3.31 => 1.3.31 
      @tarojs/taro-quickapp: 1.3.31 => 1.3.31 
      @tarojs/taro-rn: 1.3.31 => 1.3.31 
      @tarojs/taro-swan: 1.3.31 => 1.3.31 
      @tarojs/taro-tt: 1.3.31 => 1.3.31 
      @tarojs/taro-weapp: 1.3.31 => 1.3.31 
      @tarojs/webpack-runner: 1.3.31 => 1.3.31 
      eslint-config-taro: 1.3.31 => 1.3.31 
      eslint-plugin-taro: 1.3.31 => 1.3.31 
      nerv-devtools: ^1.5.5 => 1.5.6 
      nervjs: ^1.5.5 => 1.5.6 
      stylelint-config-taro-rn: 1.3.31 => 1.3.31 
      stylelint-taro-rn: 1.3.31 => 1.3.31 
@taro-bot
Copy link

taro-bot bot commented Jan 7, 2020

CC @Littly

@taro-bot
Copy link

taro-bot bot commented Jan 7, 2020

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@Chen-jj Chen-jj added T-h5 Target - 编译到 H5 V-1 Version - 1.x and removed H5 labels Jul 29, 2020
@ZakaryCode ZakaryCode moved this to Done in H5 Apr 10, 2023
@ZakaryCode ZakaryCode added this to H5 Apr 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-h5 Target - 编译到 H5 V-1 Version - 1.x
Projects
Archived in project
Development

No branches or pull requests

4 participants