<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        react-native之ART繪圖方法詳解

        來源:懂視網(wǎng) 責(zé)編:小采 時間:2020-11-27 22:33:04
        文檔

        react-native之ART繪圖方法詳解

        react-native之ART繪圖方法詳解:背景 在移動應(yīng)用的開發(fā)過程中,繪制基本的二維圖形或動畫是必不可少的。然而,考慮到Android和iOS均有一套各自的API方案,因此采用一種更普遍接受的技術(shù)方案,更有利于代碼的雙平臺兼容。 art是一個旨在多瀏覽器兼容的Node style CommonJS模塊。在它
        推薦度:
        導(dǎo)讀react-native之ART繪圖方法詳解:背景 在移動應(yīng)用的開發(fā)過程中,繪制基本的二維圖形或動畫是必不可少的。然而,考慮到Android和iOS均有一套各自的API方案,因此采用一種更普遍接受的技術(shù)方案,更有利于代碼的雙平臺兼容。 art是一個旨在多瀏覽器兼容的Node style CommonJS模塊。在它

        背景

        在移動應(yīng)用的開發(fā)過程中,繪制基本的二維圖形或動畫是必不可少的。然而,考慮到Android和iOS均有一套各自的API方案,因此采用一種更普遍接受的技術(shù)方案,更有利于代碼的雙平臺兼容。

        art是一個旨在多瀏覽器兼容的Node style CommonJS模塊。在它的基礎(chǔ)上,F(xiàn)acebook又開發(fā)了React-art ,封裝art,使之可以被react.js所使用,即實現(xiàn)了前端的svg庫。然而,考慮到react.js的JSX語法,已經(jīng)支持將 等等svg標(biāo)簽直接插入到dom中(當(dāng)然此時使用的就不是react-art庫了)此外還有HTML canvas的存在,因此,在前端上,react-art并非不可替代。

        然而,在移動端,考慮到跨平臺的需求,加之web端的技術(shù)積累,react-art成為了現(xiàn)成的繪制圖形的解決方案。react-native分別在0.10.0和0.18.0上添加了ios和android平臺上對react-art的支持。

        示例代碼

        React.js和React-Native的區(qū)別,只在于下文所述的ART獲取上,然后該例子就可以同時應(yīng)用在Web端和移動端上了。react-art自帶的官方例子:Vector-Widget

        Vector-Widget額外實現(xiàn)了旋轉(zhuǎn),以及鼠標(biāo)點擊事件的旋轉(zhuǎn)加速響應(yīng)。Web端可以看到點擊加速,但是在移動端無效,原因是React Native并未對Group中onMouseDown和onMouseUp屬性作處理。本文著重于靜態(tài)svg的實現(xiàn),暫時無視動畫部分效果即可。

        ART

        在react native中ART是個非常重要的庫,它讓非常酷炫的繪圖及動畫變成了可能。需要注意的是,在React Native引入ART過程中,Android默認(rèn)就包含ART庫,IOS需要單獨(dú)添加依賴庫。

        ios添加依賴庫

        1、使用xcode中打開React-native中的iOS項目,選中‘Libraries'目錄 ——> 右鍵選擇‘Add Files to 項目名稱' ——> ‘node_modules/react-native/Libraries/ART/ART.xcodeproj' 添加;

        這里寫圖片描述

        2、選中項目根目錄 ——> 點擊'Build Phases‘ ——> 點擊‘Link Binary With Libraries' ——> 點擊左下方‘+' ——> 選中‘libART.a'添加。

        這里寫圖片描述

        基礎(chǔ)組件

        ART暴露的組件共有7個,本文介紹常用的四個組件:Surface、Group、Shape、Text。

      1. Surface - 一個矩形可渲染的區(qū)域,是其他元素的容器
      2. Group - 可容納多個形狀、文本和其他的分組
      3. Shape - 形狀定義,可填充
      4. Text - 文本形狀定義
      5. 屬性

        Surface

      6. width : 渲染區(qū)域的寬
      7. height : 定義渲染區(qū)域的高
      8. Shape

      9. d : 定義繪制路徑
      10. stroke : 描邊顏色
      11. strokeWidth : 描邊寬度
      12. strokeDash : 定義虛線
      13. fill : 填充顏色
      14. Text

      15. funt : 字體樣式,定義字體、大小、是否加粗 如: bold 35px Heiti SC
      16. Path

      17. moveTo(x,y) : 移動到坐標(biāo)(x,y)
      18. lineTo(x,y) : 連線到(x,y)
      19. arc() : 繪制弧線
      20. close() : 封閉空間
      21. 代碼示例

        繪制直線

        這里寫圖片描述

        import React from 'react'
        import {
         View,
         ART
        } from 'react-native'
        
        export default class Line extends React.Component{
        
         render(){
        
         const path = ART.Path();
         path.moveTo(1,1); //將起始點移動到(1,1) 默認(rèn)(0,0)
         path.lineTo(300,1); //連線到目標(biāo)點(300,1)
        
         return(
         <View style={this.props.style}>
         <ART.Surface width={300} height={2}>
         <ART.Shape d={path} stroke="#000000" strokeWidth={1} />
         </ART.Surface>
         </View>
         )
         }
        }
        
        

        繪制虛線

        了解strokeDash的參數(shù),

        [10,5] : 表示繪10像素實線在繪5像素空白,如此循環(huán)

        [10,5,20,5] : 表示繪10像素實線在繪制5像素空白在繪20像素實線及5像素空白

        這里寫圖片描述

        import React from 'react'
        import {
         View,
         ART
        } from 'react-native'
        
        const {Surface, Shape, Path} = ART;
        
        export default class DashLine extends React.Component{
        
         render(){
        
         const path = Path()
         .moveTo(1,1)
         .lineTo(300,1);
        
         return(
         <View style={this.props.style}>
         <Surface width={300} height={2}>
         <Shape d={path} stroke="#000000" strokeWidth={2} strokeDash={[10,5]}/>
         </Surface>
         </View>
         )
         }
        }
        
        

        繪制矩形

        首先通過lineTo繪制三條邊,在使用close鏈接第四條邊。fill做顏色填充.

        這里寫圖片描述

        import React from 'react'
        import {
         View,
         ART
        } from 'react-native'
        
        const {Surface, Shape, Path} = ART;
        
        export default class Rect extends React.Component{
        
         render(){
        
         const path = new Path()
         .moveTo(1,1)
         .lineTo(1,99)
         .lineTo(99,99)
         .lineTo(99,1)
         .close();
        
         return(
         <View style={this.props.style}>
         <Surface width={100} height={100}>
         <Shape d={path} stroke="#000000" fill="#892265" strokeWidth={1} />
         </Surface>
         </View>
         )
         }
        }
        
        

        繪圓

        了解arc(x,y,radius)的使用, 終點坐標(biāo)距離起點坐標(biāo)的相對距離。

        這里寫圖片描述

        import React from 'react'
        import {
         View,
         ART
        } from 'react-native'
        
        const {Surface, Shape, Path} = ART;
        
        export default class Circle extends React.Component{
        
         render(){
        
         const path = new Path()
         .moveTo(50,1)
         .arc(0,99,25)
         .arc(0,-99,25)
         .close();
        
        
         return(
         <View style={this.props.style}>
         <Surface width={100} height={100}>
         <Shape d={path} stroke="#000000" strokeWidth={1}/>
         </Surface>
         </View>
         )
         }
        }
        
        

        繪制文字

        了解funt屬性的使用,規(guī)則是“粗細(xì) 字號 字體”

        注意: 字體應(yīng)該是支持path屬性的,應(yīng)該是實現(xiàn)bug并沒有不生效。 Android通過修改源碼是可以解決的,IOS沒看源碼。

        這里寫圖片描述

        import React, {Component} from 'react';
        import {
         AppRegistry,
         StyleSheet,
         ART,
         View
        } from 'react-native';
        
        const {Surface, Text, Path} = ART;
        
        export default class ArtTextView extends Component {
        
         render() {
        
         return (
         <View style={styles.container}>
         <Surface width={100} height={100}>
         <Text strokeWidth={1} stroke="#000" font="bold 35px Heiti SC" path={new Path().moveTo(40,40).lineTo(99,10)} >React</Text>
         </Surface>
        
         </View>
        
         );
         }
        }
        
        const styles = StyleSheet.create({
         container: {
         flex: 1,
         justifyContent: 'center',
         alignItems: 'center',
         backgroundColor: '#F5FCFF',
         },
        
        });
        
        

        繪制扇形

        這里寫圖片描述

        在這里需要使用arc做路徑繪制。

        Wedge.js

        import React, { Component, PropTypes } from 'react';
        import { ART } from 'react-native';
        const { Shape, Path } = ART;
        
        /**
         * Wedge is a React component for drawing circles, wedges and arcs. Like other
         * ReactART components, it must be used in a <Surface>.
         */
        export default class Wedge extends Component<void, any, any> {
        
         static propTypes = {
         outerRadius: PropTypes.number.isRequired,
         startAngle: PropTypes.number.isRequired,
         endAngle: PropTypes.number.isRequired,
         originX: PropTypes.number.isRequired,
         originY: PropTypes.number.isRequired,
         innerRadius: PropTypes.number,
         };
        
        
         constructor(props : any) {
         super(props);
         (this:any).circleRadians = Math.PI * 2;
         (this:any).radiansPerDegree = Math.PI / 180;
         (this:any)._degreesToRadians = this._degreesToRadians.bind(this);
         }
        
         /**
         * _degreesToRadians(degrees)
         *
         * Helper function to convert degrees to radians
         *
         * @param {number} degrees
         * @return {number}
         */
         _degreesToRadians(degrees : number) : number {
         if (degrees !== 0 && degrees % 360 === 0) { // 360, 720, etc.
         return (this:any).circleRadians;
         }
         return degrees * (this:any).radiansPerDegree % (this:any).circleRadians;
         }
        
         /**
         * _createCirclePath(or, ir)
         *
         * Creates the ReactART Path for a complete circle.
         *
         * @param {number} or The outer radius of the circle
         * @param {number} ir The inner radius, greater than zero for a ring
         * @return {object}
         */
         _createCirclePath(or : number, ir : number) : Path {
         const path = new Path();
        
         path.move(0, or)
         .arc(or * 2, 0, or)
         .arc(-or * 2, 0, or);
        
         if (ir) {
         path.move(or - ir, 0)
         .counterArc(ir * 2, 0, ir)
         .counterArc(-ir * 2, 0, ir);
         }
        
         path.close();
        
         return path;
         }
        
         /**
         * _createArcPath(sa, ea, ca, or, ir)
         *
         * Creates the ReactART Path for an arc or wedge.
         *
         * @param {number} startAngle The starting degrees relative to 12 o'clock
         * @param {number} endAngle The ending degrees relative to 12 o'clock
         * @param {number} or The outer radius in pixels
         * @param {number} ir The inner radius in pixels, greater than zero for an arc
         * @return {object}
         */
         _createArcPath(originX : number, originY : number, startAngle : number, endAngle : number, or : number, ir : number) : Path {
         const path = new Path();
        
         // angles in radians
         const sa = this._degreesToRadians(startAngle);
         const ea = this._degreesToRadians(endAngle);
        
         // central arc angle in radians
         const ca = sa > ea ? (this:any).circleRadians - sa + ea : ea - sa;
        
         // cached sine and cosine values
         const ss = Math.sin(sa);
         const es = Math.sin(ea);
         const sc = Math.cos(sa);
         const ec = Math.cos(ea);
        
         // cached differences
         const ds = es - ss;
         const dc = ec - sc;
         const dr = ir - or;
        
         // if the angle is over pi radians (180 degrees)
         // we will need to let the drawing method know.
         const large = ca > Math.PI;
        
         // TODO (sema) Please improve theses comments to make the math
         // more understandable.
         //
         // Formula for a point on a circle at a specific angle with a center
         // at (0, 0):
         // x = radius * Math.sin(radians)
         // y = radius * Math.cos(radians)
         //
         // For our starting point, we offset the formula using the outer
         // radius because our origin is at (top, left).
         // In typical web layout fashion, we are drawing in quadrant IV
         // (a.k.a. Southeast) where x is positive and y is negative.
         //
         // The arguments for path.arc and path.counterArc used below are:
         // (endX, endY, radiusX, radiusY, largeAngle)
        
         path.move(or + or * ss, or - or * sc) // move to starting point
         .arc(or * ds, or * -dc, or, or, large) // outer arc
         .line(dr * es, dr * -ec); // width of arc or wedge
        
         if (ir) {
         path.counterArc(ir * -ds, ir * dc, ir, ir, large); // inner arc
         }
        
         return path;
         }
        
         render() : any {
         // angles are provided in degrees
         const startAngle = this.props.startAngle;
         const endAngle = this.props.endAngle;
         // if (startAngle - endAngle === 0) {
         // return null;
         // }
        
         // radii are provided in pixels
         const innerRadius = this.props.innerRadius || 0;
         const outerRadius = this.props.outerRadius;
        
         const { originX, originY } = this.props;
        
         // sorted radii
         const ir = Math.min(innerRadius, outerRadius);
         const or = Math.max(innerRadius, outerRadius);
        
         let path;
         if (endAngle >= startAngle + 360) {
         path = this._createCirclePath(or, ir);
         } else {
         path = this._createArcPath(originX, originY, startAngle, endAngle, or, ir);
         }
        
         return <Shape {...this.props} d={path} />;
         }
        }
        
        

        示例代碼:

        import React from 'react'
        import {
         View,
         ART
        } from 'react-native'
        
        const {Surface} = ART;
        import Wedge from './Wedge'
        
        export default class Fan extends React.Component{
        
         render(){
        
         return(
         <View style={this.props.style}>
         <Surface width={100} height={100}>
         <Wedge
         outerRadius={50}
         startAngle={0}
         endAngle={60}
         originX={50}
         originY={50}
         fill="blue"/>
        
         </Surface>
         </View>
         )
         }
        }
        
        

        綜合示例

        這里寫圖片描述

        相關(guān)代碼:

        /**
         * Sample React Native App
         * https://github.com/facebook/react-native
         * @flow
         */
        
        import React, {
         Component
        }from 'react';
        import {
         ART as Art,
         StyleSheet,
         View,
         Dimensions,
         TouchableWithoutFeedback,
         Animated
        } from 'react-native';
        
        var HEART_SVG = "M130.4-0.8c25.4 0 46 20.6 46 46.1 0 13.1-5.5 24.9-14.2 33.3L88 153.6 12.5 77.3c-7.9-8.3-12.8-19.6-12.8-31.9 0-25.5 20.6-46.1 46-46.2 19.1 0 35.5 11.7 42.4 28.4C94.9 11 111.3-0.8 130.4-0.8"
        var HEART_COLOR = 'rgb(226,38,77,1)';
        var GRAY_HEART_COLOR = "rgb(204,204,204,1)";
        
        var FILL_COLORS = [
         'rgba(221,70,136,1)',
         'rgba(212,106,191,1)',
         'rgba(204,142,245,1)',
         'rgba(204,142,245,1)',
         'rgba(204,142,245,1)',
         'rgba(0,0,0,0)'
        ];
        
        var PARTICLE_COLORS = [
         'rgb(158, 202, 250)',
         'rgb(161, 235, 206)',
         'rgb(208, 148, 246)',
         'rgb(244, 141, 166)',
         'rgb(234, 171, 104)',
         'rgb(170, 163, 186)'
        ]
        
        getXYParticle = (total, i, radius) => {
         var angle = ( (2 * Math.PI) / total ) * i;
        
         var x = Math.round((radius * 2) * Math.cos(angle - (Math.PI / 2)));
         var y = Math.round((radius * 2) * Math.sin(angle - (Math.PI / 2)));
         return {
         x: x,
         y: y,
         }
        }
        
        getRandomInt = (min, max) => {
         return Math.floor(Math.random() * (max - min)) + min;
        }
        
        shuffleArray = (array) => {
         for (var i = array.length - 1; i > 0; i--) {
         var j = Math.floor(Math.random() * (i + 1));
         var temp = array[i];
         array[i] = array[j];
         array[j] = temp;
         }
         return array;
        }
        
        
        var {
         Surface,
         Group,
         Shape,
         Path
        } = Art;
        
        //使用Animated.createAnimatedComponent對其他組件創(chuàng)建對話
        //創(chuàng)建一個灰色的新型圖片
        var AnimatedShape = Animated.createAnimatedComponent(Shape);
        
        var {
         width: deviceWidth,
         height: deviceHeight
        } = Dimensions.get('window');
        
        export default class ArtAnimView extends Component {
         constructor(props) {
         super(props);
        
         this.state = {
         animation: new Animated.Value(0)
         };
         }
        
         explode = () => {
         Animated.timing(this.state.animation, {
         duration: 1500,
         toValue: 28
         }).start(() => {
         this.state.animation.setValue(0);
         this.forceUpdate();
         });
         }
        
         getSmallExplosions = (radius, offset) => {
         return [0, 1, 2, 3, 4, 5, 6].map((v, i, t) => {
        
         var scaleOut = this.state.animation.interpolate({
         inputRange: [0, 5.99, 6, 13.99, 14, 21],
         outputRange: [0, 0, 1, 1, 1, 0],
         extrapolate: 'clamp'
         });
        
         var moveUp = this.state.animation.interpolate({
         inputRange: [0, 5.99, 14],
         outputRange: [0, 0, -15],
         extrapolate: 'clamp'
         });
        
         var moveDown = this.state.animation.interpolate({
         inputRange: [0, 5.99, 14],
         outputRange: [0, 0, 15],
         extrapolate: 'clamp'
         });
        
         var color_top_particle = this.state.animation.interpolate({
         inputRange: [6, 8, 10, 12, 17, 21],
         outputRange: shuffleArray(PARTICLE_COLORS)
         })
        
         var color_bottom_particle = this.state.animation.interpolate({
         inputRange: [6, 8, 10, 12, 17, 21],
         outputRange: shuffleArray(PARTICLE_COLORS)
         })
        
         var position = getXYParticle(7, i, radius)
        
         return (
         <Group
         x={position.x + offset.x }
         y={position.y + offset.y}
         rotation={getRandomInt(0, 40) * i}
         >
         <AnimatedCircle
         x={moveUp}
         y={moveUp}
         radius={15}
         scale={scaleOut}
         fill={color_top_particle}
         />
         <AnimatedCircle
         x={moveDown}
         y={moveDown}
         radius={8}
         scale={scaleOut}
         fill={color_bottom_particle}
         />
         </Group>
         )
         }, this)
         }
        
         render() {
         var heart_scale = this.state.animation.interpolate({
         inputRange: [0, .01, 6, 10, 12, 18, 28],
         outputRange: [1, 0, .1, 1, 1.2, 1, 1],
         extrapolate: 'clamp'
         });
        
         var heart_fill = this.state.animation.interpolate({
         inputRange: [0, 2],
         outputRange: [GRAY_HEART_COLOR, HEART_COLOR],
         extrapolate: 'clamp'
         })
        
         var heart_x = heart_scale.interpolate({
         inputRange: [0, 1],
         outputRange: [90, 0],
         })
        
         var heart_y = heart_scale.interpolate({
         inputRange: [0, 1],
         outputRange: [75, 0],
         })
        
         var circle_scale = this.state.animation.interpolate({
         inputRange: [0, 1, 4],
         outputRange: [0, .3, 1],
         extrapolate: 'clamp'
         });
        
         var circle_stroke_width = this.state.animation.interpolate({
         inputRange: [0, 5.99, 6, 7, 10],
         outputRange: [0, 0, 15, 8, 0],
         extrapolate: 'clamp'
         });
        
         var circle_fill_colors = this.state.animation.interpolate({
         inputRange: [1, 2, 3, 4, 4.99, 5],
         outputRange: FILL_COLORS,
         extrapolate: 'clamp'
         })
        
         var circle_opacity = this.state.animation.interpolate({
         inputRange: [1, 9.99, 10],
         outputRange: [1, 1, 0],
         extrapolate: 'clamp'
         })
        
        
         return (
         <View style={styles.container}>
         <TouchableWithoutFeedback onPress={this.explode} style={styles.container}>
         <View style={{transform: [{scale: .8}]}}>
         <Surface width={deviceWidth} height={deviceHeight}>
         <Group x={75} y={200}>
         <AnimatedShape
         d={HEART_SVG}
         x={heart_x}
         y={heart_y}
         scale={heart_scale}
         fill={heart_fill}
         />
         <AnimatedCircle
         x={89}
         y={75}
         radius={150}
         scale={circle_scale}
         strokeWidth={circle_stroke_width}
         stroke={FILL_COLORS[2]}
         fill={circle_fill_colors}
         opacity={circle_opacity}
         />
        
         {this.getSmallExplosions(75, {x: 89, y: 75})}
         </Group>
         </Surface>
         </View>
         </TouchableWithoutFeedback>
         </View>
         );
         }
        };
        
        class AnimatedCircle extends Component {
         render() {
         var radius = this.props.radius;
         var path = Path().moveTo(0, -radius)
         .arc(0, radius * 2, radius)
         .arc(0, radius * -2, radius)
         .close();
         return React.createElement(AnimatedShape);
         }
        }
        
        var styles = StyleSheet.create({
         container: {
         flex: 1,
         }
        });
        
        

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        react-native之ART繪圖方法詳解

        react-native之ART繪圖方法詳解:背景 在移動應(yīng)用的開發(fā)過程中,繪制基本的二維圖形或動畫是必不可少的。然而,考慮到Android和iOS均有一套各自的API方案,因此采用一種更普遍接受的技術(shù)方案,更有利于代碼的雙平臺兼容。 art是一個旨在多瀏覽器兼容的Node style CommonJS模塊。在它
        推薦度:
        標(biāo)簽: 繪制 art 繪制圖形
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 最近的2019免费中文字幕| 亚洲中文无码亚洲人成影院| 亚洲色一色噜一噜噜噜| 日本红怡院亚洲红怡院最新| 亚洲AV成人片色在线观看 | 男女一进一出抽搐免费视频| 美景之屋4在线未删减免费| 一级特级女人18毛片免费视频| 久久午夜免费鲁丝片| 在线观看成人免费| 国产亚洲成人久久| 亚洲变态另类一区二区三区| 两个人日本免费完整版在线观看1| 亚洲欧洲精品成人久久曰影片| 亚洲精品**中文毛片| 羞羞漫画页面免费入口欢迎你| 又粗又黄又猛又爽大片免费| 蜜芽亚洲av无码精品色午夜| 四虎精品免费永久免费视频| 成人片黄网站A毛片免费| 精品国产亚洲一区二区三区| 色窝窝亚洲av网| 无码av免费毛片一区二区| 久久久久亚洲av毛片大| 久草免费手机视频| 亚洲成人免费网站| 久久国产精品一区免费下载| 亚洲毛片一级带毛片基地| 免费看少妇作爱视频| 亚洲Av高清一区二区三区| 久久国产乱子伦精品免费强| 国产亚洲美日韩AV中文字幕无码成人 | 日本黄色动图免费在线观看| 亚洲激情校园春色| 国产精品va无码免费麻豆| 国产 亚洲 中文在线 字幕| 美女内射毛片在线看免费人动物| JLZZJLZZ亚洲乱熟无码| 日本一卡精品视频免费| 亚洲男人第一av网站| 久久久免费的精品|