|
[[415355]] 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。 https://harmonyos..com 最終結果: 実装プロセスの分析: 1. 外部からコンポーネントに渡される配列(ボールのエネルギーのリスト)と、エネルギー収集アニメーションが終了する位置を受け取ります。 - <!
- 小道具: {
- // バックエンドから返されたボール情報
- ボールリスト: {
- デフォルト: [10, 11, 12, 13, 14],
- },
- // エネルギー収集アニメーション終了時のX座標
- コリジョン宛先X: {
- デフォルト: 350
- },
- // エネルギー収集アニメーション終了時のY座標
- 照合先Y: {
- デフォルト: 400
- }
- },
2. ボールの数に基づいて、各ボールのランダムな位置座標を生成します。 - // ボールのx座標配列を生成する
- xRandom = this.randomCommon(1, 8, this.ballList.length) とします。
- all_x = xRandom.map(item => {
- アイテム * 幅 * 0.10を返す
- });
- // ボールのy座標配列を生成する
- yRandom = this.randomCommon(1, 8, this.ballList.length); とします。
- all_y = yRandom.map(item => {
- 返されるアイテム * 高さ * 0.08
- })
- /**
- * 指定された範囲から N 個の一意の番号をランダムに選択します。
- * 最もシンプルで基本的な方法
- *
- * @param min範囲内の最小値を指定します
- * @param max指定された範囲内の最大値を指定します。
- * @param n 乱数の数
- * @乱数のリストを返す
- /
- ランダムコモン(最小,最大,n){
- もし (n > (最大値-最小値+ 1) ||最大値<最小値) {
- 戻る ヌル;
- }
- 結果を [] とします。
- count = 0 とします。
- while ( count < n) {
- let num = parseInt((Math.random() * ( max - min )) + min );
- フラグをtrueにします。
- (j = 0; j < n; j++)の場合
- if (num == result[j]) {
- フラグ = false ;
- 壊す
- }
- }
- if (フラグ) {
- 結果[ count ] = num;
- カウント++;
- }
- }
- 結果を返します。
- },
3. 入力エネルギー リストと生成されたボールの座標に基づいて、必要なボール データ リストを ballDataList[] に組み立てます。 - /**
- ballDataList 内の各オブジェクトには、次のプロパティが含まれます。
- * コンテンツ(ボールに表示されるテキスト情報)
- * x(水平座標)
- * y(垂直軸)
- /
- ボールデータリスト: [],
- データリストを [] とします
- for (let index = 0; index < this.ballList.length; index ++) {
- データリスト.push({
- コンテンツ: this.ballList[インデックス] + 'g' 、
- x: all_x[インデックス],
- y: all_y[インデックス]
- })
- }
- this.ballDataList = dataList; // ビューの更新をトリガーする
4. 小さなボールをランダムに表示するためのインターフェースを描画します。 - <!
- <div class= "main_contain" ref= "main_contain" id= "main_contain" >
- <text for = "{{ ballDataList }}"
- スタイル="上: {{ $item.y }} px;
- 左: {{ $item.x }} ピクセル;
- >{{ $item.content } } テキスト>
-
- </div>
- .main_contain {
- 幅: 100%;
- 位置:相対;
- }
-
- 。ボール {
- 幅: 120px;
- 高さ: 120px;
- 背景色: #c3f593;
- 背景サイズ:100%;
- 境界線の半径: 60px;
- 境界線: #69c78e;
- ボーダーボトムスタイル: solid;
- 境界線の幅: 1px;
- 位置:絶対;
- テキスト配置: 中央;
- }
5. ボールにアニメーションを追加します。 HarmonyOS JSUI フレームワークの @keyframes アニメーションでは、初期アニメーション スタイル (from プロパティ) と終了スタイル (to プロパティ) のみを指定できるため、ボールのアニメーションを指定するには JS を使用するしかありません。 ボールが単純な上下運動をするアニメーションは、次の 2 つの方法で実装できます。 方法 1: 各ボールのアニメーションを無限回設定します。 - createShakeAnimate(el) {
- if (el == null || el == 未定義) {
- 戻る
- }
- var オプション = {
- 期間: 2000年、
- 緩和: 「摩擦」 、
- 塗りつぶし: '前方' 、
- 反復回数: 「無限」 、
- };
- var フレーム = [
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- offset: 0.0 // アニメーション開始時
- },
- {
- 変身: {
- 翻訳: '0px 20px'
- },
- offset: 0.5 // アニメーションが半分終わったとき。
- },
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- offset: 1.0 // アニメーションが終了したとき
- },
-
- ];
- アニメーションを el.animate(フレーム、オプション) とします。
- リターンアニメーション
- },
方法 2: 各ボールを一方向のアニメーションに設定し、それを 1 回だけ実行し、アニメーションが終了したら reverse() メソッドを呼び出してアニメーションを反転します。 - createShakeAnimate(el) {
- if (el == null || el == 未定義) {
- 戻る
- }
- var オプション = {
- 期間: 2000年、
- 緩和: 「摩擦」 、
- 塗りつぶし: '前方'
- 反復回数: 1,
- };
- var フレーム = [
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- オフセット: 0.0
- },
- {
- 変身: {
- 翻訳: '0px 20px'
- },
- オフセット: 1.0
- },
- ];
- アニメーションを el.animate(フレーム、オプション) とします。
- アニメーション.onfinish =関数() {
- アニメーション.逆()
- };
- リターンアニメーション
フローティングアニメーションを実行する - <!
- <text for = "{{ ballDataList }}"
- クラス= "ボール"
- id= "ボール{{ $idx }}"
- onclick = "onBallClick($idx,$item)"
- スタイル="上: {{ $item.y }} px;
- 左: {{ $item.x }} ピクセル;
- >{{ $item.content } } テキスト>
- <!
- プレイシェイクアニメーション() {
- setTimeout(() => {
- console.info( 'xwg playShakeAnimate ' );
- for (var index = 0; index < this.ballDataList.length; index ++) {
- el = this.$element(`ball${ index }`)とします。
- animate = this.createShakeAnimate(el) とします。
- アニメーション再生()
- }
- }, 50)
- },
6. ボールのクリック イベントとエネルギー収集アニメーションを設定します。 - onBallClick(インデックス, アイテム ) {
- // イベントを親コンポーネントに送信し、ボール情報をパラメーターとして渡します。
- this.$emit( 'ballClick' , item);
-
- el = this.$element(`ball${ index }`)とします。
- this.playCollectionAnimate(el,インデックス)
- },
- /**
- * 収集したアニメーションを実行する
- * @param el
- * @paramインデックス
- * @戻る
- /
- playCollectionAnimate(el,インデックス) {
- if (this.isCollect) { // コレクションアニメーションが進行中の場合は、すぐに戻ります。
- 戻る
- }
- var オプション = {
- 所要時間: 1500
- イージング: 'ease-in-out' 、
- 塗りつぶし: '前方'
- };
- offsetX = this.collDestinationX - this.ballDataList[インデックス].xとします。
- offsetY = this.collDestinationY - this.ballDataList[インデックス].yとします。
- var フレーム = [
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- 不透明度: 1
- },
- {
- 変身: {
- 翻訳: `${offsetX}px ${offsetY}px`
- },
- 不透明度: 0
- }
- ];
- アニメーションを el.animate(フレーム、オプション) とします。
- _t = これ
- アニメーション.onfinish =関数() {
- console.info( 'onBallClick コレクションアニメーション onFinish' );
- _t.isCollect = false ;
- _t.ballDataList.splice(インデックス, 1);
- console.info(JSON.stringify(_t.ballDataList));
-
- // splice メソッドを呼び出した後、元のインデックス位置にあるボールはアニメーションしなくなるため、アニメーションを手動で作成する必要があります。
- if (インデックス<= _t.ballDataList.length) {
- setTimeout(() => {
- animate = _t.createShakeAnimate(el) とします。
- アニメーション再生()
- }, 5)
- }
- };
- this.isCollect = true
- アニメーション.再生()
- },
7. 親コンポーネントがリセットをクリックしたら、インターフェースを更新します。 - onInit() {
- this.$watch( 'ballList' , 'onBallListChange' ); // データ変更のリスナーを登録する
- },
- onBallListChange(newV) { // 外部データが変更されたら、コンポーネントを再レンダリングします。
- console.log( 'onBallListChange newV = ' + JSON.stringify(newV))
- this.onReady()
- }
完全なコードは次のとおりです。子コンポーネント:- <!
- .main_contain {
- 幅: 100%;
- 位置:相対;
- }
-
- 。ボール {
- 幅: 100px;
- 高さ: 100px;
- 背景色: #c3f593;
- 背景サイズ:100%;
- 境界線の半径: 60px;
- 境界線: #69c78e;
- ボーダーボトムスタイル: solid;
- 境界線の幅: 1px;
- 位置:絶対;
- テキスト配置: 中央;
- }
-
- @keyframes 波 {
- から{
- 変換: translateY(0px);
- }
-
- に{
- 変換: translateY(10px);
- }
- }
- <!
- <div class= "main_contain" ref= "main_contain" id= "main_contain" >
- <text for = "{{ ballDataList }}"
- ref= "ボール{{ $idx }}"クラス= "ボール"
- id= "ボール{{ $idx }}"
- tid= "ボール{{ $idx }}"
- onclick = "onBallClick($idx,$item)"
- スタイル="上: {{ $item.y }} px;
- 左: {{ $item.x }} ピクセル;
- >{{ $item.content } } テキスト>
-
- </div>
- <!
- エクスポートデフォルト{
- 小道具: {
- // バックエンドから返されたボール情報
- ボールリスト: {
- デフォルト: [10, 11, 12, 13, 14],
- },
- // エネルギー収集アニメーション終了時のX座標
- コリジョン宛先X: {
- デフォルト: 0
- },
- // エネルギー収集アニメーション終了時のY座標
- 照合先Y: {
- デフォルト: 600
- }
- },
- データ() {
- 戻る{
- /**
- ballDataList 内の各オブジェクトには、次のプロパティが含まれます。
- * コンテンツ(ボールに表示されるテキスト情報)
- * x(水平座標)
- * y(垂直座標)
- /
- ボールデータリスト: [],
- isCollect: false // エネルギー収集アニメーションが現在実行中かどうか
- };
- },
- onInit() {
- this.$watch( 'ballList' , 'onBallListChange' ); // データ変更のリスナーを登録する
- },
- onReady() {
- let width = 720 // コンポーネントの幅
- let height = 600 // コンポーネントの高さ
- // ボールのx座標配列を生成する
- xRandom = this.randomCommon(1, 8, this.ballList.length) とします。
- all_x = xRandom.map(item => {
- アイテム * 幅 * 0.10を返す
- });
- // ボールのy座標配列を生成する
- yRandom = this.randomCommon(1, 8, this.ballList.length); とします。
- all_y = yRandom.map(item => {
- アイテム * 高さ * 0.08を返す
- })
- xランダム == null || yランダム == nullの場合
- 戻る
- }
- データリストを [] とします
- for (let index = 0; index < this.ballList.length; index ++) {
- データリスト.push({
- コンテンツ: this.ballList[インデックス] + 'g' 、
- x: all_x[インデックス],
- y: all_y[インデックス]
- })
- }
- this.ballDataList = dataList; // ビューの更新をトリガーする
- console.info( 'onReady ballDataList = ' + JSON.stringify(this.ballDataList));
-
- this.playShakeAnimate() // 揺れアニメーションを開始します
- },
- onBallClick(インデックス, アイテム ) {
- console.info( 'onBallClick index = ' + index );
- console.info( 'onBallClick item = ' + JSON.stringify(item));
- this.$emit( 'ballClick' , item);
- el = this.$element(`ball${ index }`)とします。
- this.playCollectionAnimate(el,インデックス)
- },
- /**
- * 収集したアニメーションを実行する
- * @param el
- * @paramインデックス
- * @戻る
- /
- playCollectionAnimate(el,インデックス) {
- if (this.isCollect) { // コレクションアニメーションが進行中の場合は、すぐに戻ります。
- 戻る
- }
- var オプション = {
- 所要時間: 1500,
- イージング: 'ease-in-out' 、
- 塗りつぶし: '前方' 、
- };
- offsetX = this.collDestinationX - this.ballDataList[インデックス].xとします。
- offsetY = this.collDestinationY - this.ballDataList[インデックス].yとします。
- var フレーム = [
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- 不透明度: 1
- },
- {
- 変身: {
- 翻訳: `${offsetX}px ${offsetY}px`
- },
- 不透明度: 0
- }
- ];
- アニメーションを el.animate(フレーム、オプション) とします。
- _t = これ
- アニメーション.onfinish =関数() {
- console.info( 'onBallClick コレクションアニメーション onFinish' );
- _t.isCollect = false ;
- _t.ballDataList.splice(インデックス, 1);
- console.info(JSON.stringify(_t.ballDataList));
-
- // splice メソッドを呼び出した後、元のインデックス位置にあるボールはアニメーションしなくなるため、アニメーションを手動で作成する必要があります。
- if (インデックス<= _t.ballDataList.length) {
- setTimeout(() => {
- animate = _t.createShakeAnimate(el) とします。
- アニメーション再生()
- }, 5)
- }
- };
- this.isCollect = true
- アニメーション.再生()
- },
- createShakeAnimate(el) {
- if (el == null || el == 未定義) {
- 戻る
- }
- var オプション = {
- 期間: 2000年、
- 緩和: 「摩擦」 、
- 塗りつぶし: '前方' 、
- 反復回数: 「無限」 、
- };
- var フレーム = [
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- オフセット: 0.0
- },
- {
- 変身: {
- 翻訳: '0px 20px'
- },
- オフセット: 0.5
- },
- {
- 変身: {
- 翻訳: '0px 0px'
- },
- オフセット: 1.0
- },
-
- ];
- アニメーションを el.animate(フレーム、オプション) とします。
- リターンアニメーション
- },
- プレイシェイクアニメーション() {
- setTimeout(() => {
- console.info( 'xwg playShakeAnimate ' );
- for (var index = 0; index < this.ballDataList.length; index ++) {
- el = this.$element(`ball${ index }`)とします。
- animate = this.createShakeAnimate(el) とします。
- アニメーション再生()
- }
- }, 50)
- },
- /**
- * 指定された範囲から N 個の一意の番号をランダムに選択します。
- * 最もシンプルで基本的な方法
- *
- * @param min範囲内の最小値を指定します
- * @param max指定された範囲内の最大値を指定します。
- * @param n 乱数の数
- * @乱数のリストを返す
- /
- ランダムコモン(最小,最大,n){
- もし (n > (最大値-最小値+ 1) ||最大値<最小値) {
- 戻る ヌル;
- }
- 結果を [] とします。
- count = 0 とします。
- while ( count < n ) {
- let num = parseInt((Math.random() * ( max - min )) + min );
- フラグをtrueにします。
- (j = 0; j < n; j++)の場合
- if (num == result[j]) {
- フラグ = false ;
- 壊す
- }
- }
- if (フラグ) {
- 結果[ count ] = num;
- カウント++;
- }
- }
- 結果を返します。
- },
- onBallListChange(newV) { // 外部データが変更されたら、コンポーネントを再レンダリングします。
- console.log( 'onBallListChange newV = ' + JSON.stringify(newV))
- this.onReady()
- }
- }
親コンポーネント:- <!
- 。容器 {
- flex-direction:列;
- align-items: flex-start;
- }
-
- 。タイトル {
- フォントサイズ: 100px;
- }
-
- .forestContainer {
- 幅: 100%;
- 高さ: 750px;
- 背景画像: url( "/common/bg.jpg" );
- 背景サイズ:100%;
- background-repeat: -repeatなし;
- }
- <!
- <要素名= 'waterFlake' src = '../../../default/common/component/waterflake/waterFlake.hml' ></要素>
- <div クラス = "コンテナ" >
- <div クラス = "forestContainer" >
- <waterFlake ボールリスト = "{{ ballList }}" @ボールクリック = "onBallClick" ></waterFlake>
- </div>
- <button style= "padding : 20px; align-content : center; background-color : #222222;"
- onclick= "reset" >リセット
- </ボタン>
-
- </div>
- <!
- インポートプロンプト '@system.prompt' ;
- エクスポートデフォルト{
- データ() {
- 戻る{
- ボールリスト: []
- }
- },
- onInit() {
- this.ballList = this.genRandomArray(5);
- },
- onBallClick(情報) {
- console.info( 'xwg 親 onBallClick 項目 = ' + JSON.stringify(info.detail));
- コンテンツ = info.detail.content とします
- prompt.showToast({message:`${content} をクリックしました`,duration:1500})
- },
- リセット(){
- console.info( "xwg リセットがクリックされました " )
- this.ballList = this.genRandomArray(6);
- console.info( "xwg リセット ballList = " + JSON.stringify(this.ballList))
- },
- genRandomArray(カウント) {
- ballArray = [] とします
- for (var index = 0; index < count ; index ++) {
- v = this.random(1, 60) とします。
- ballArray.push(parseInt(v))
- }
- ballArrayを返す
- },
- ランダム(最小,最大){
- Math.floor(Math.random() * ( max - min )) + minを返します。
- }
- }
詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHarmonyOSテクノロジーコミュニティ。 https://harmonyos..com |