擬似3D効果

最近、彼はいわゆる擬似3D効果が実装されているプログラムのコマーシャルに注目しました。アプリケーションの画像は、電話に対するユーザーの位置に応じて変化します。 またはユーザーに関する電話:あなたがどちら側にあるかに応じて:)。 この効果を実現するには、センサーを使用するか、ユーザーの目の位置を追跡します(いわゆるヘッドトラッキング)。 2番目の方法はやや複雑ですが、より妥当な結果が得られます。

実験として、 Deluxe Moon Proプログラムでこのような3D背景を作成することにしました(市場に出ているバージョンでは、この効果はまだ実装されていません!)。

取得したものの例を次に示します。


それでは始めましょう。

3D効果を実現するには、画像を「レイヤー」に分割し、加速度計に応じて各レイヤーを一定量シフトする必要があります。

簡単に思えますが、いくつかの問題があります。

  1. 握手がちらつきを引き起こす
  2. 電話が傾いています。 したがって、プログラムを開始するときは、この位置でユーザーの視線が電話の平面に垂直に向けられ、センサーのすべての変更がこの初期値からカウントされると想定する方が適切です。

したがって、この問題を解決する一般的なアプローチは次のとおりです。

  1. 背景をいくつかのレイヤーに分割し、レイヤーを互いに相対的に移動します。 テキスト、背景画像、または「深さ」を与えるために作成された特別な要素です。
  2. 加速度計イベントを購読します。
  3. 加速度計を変更する場合:
  4. 初期値に対するセンサーの性能を修正します。
  5. 滑らかな握手
  6. 各レイヤーを独自のサイズにシフトします。
  7. センサーをオプションにします。すべてのユーザーがこの驚きを好むわけではありません。

したがって、この場合、背景画像、+ 2層の星、+さまざまな画面要素の層があります。

フィルタリングのニーズに合わせて、いくつかの定数を設定します。
#define kUpdateFrequency 240.0 //   #define kCutoffFrequency 5.0 //  #define kAccDataScale 2.2 //  

プログラムの起動時に、手ぶれによるバックグラウンドのがたつきを取り除くために、ローパスフィルターを初期化します。
あなたは彼についてここで読むことができます
Appleから実装例をダウンロードしてください
 -(void)awakeFromNib { filter = [[LowpassFilter alloc] initWithSampleRate:kUpdateFrequency/10 cutoffFrequency:kCutoffFrequency]; //    if ([Options instance].useSensors) { [self performSelector:@selector(startAcc) withObject:nil afterDelay:4]; //              } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didGoToBG:) name:UIApplicationDidEnterBackgroundNotification object:nil]; //    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didResume:) name:UIApplicationDidBecomeActiveNotification object:nil]; //   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(useSensorsChanged) name:@"useSensors" object:nil]; //    } 

3Dバックグラウンド効果をオン/オフにするオプションを変更し、プログラムをバックグラウンドに最小化することに対する反応を説明する価値はないと思います。

この美しさをすべて引き出す機能を考えてみましょう
PS保持または解放がないため、ARCによって使用されます
 -(void)startAcc { @try { if (!acc) { startY = 100; //     Y          acc = [UIAccelerometer sharedAccelerometer]; acc.updateInterval = 1/kUpdateFrequency; acc.delegate = self; } } @catch (NSException *exception) { NSLog(@"startAcc %@",exception); } } 

このすべてを止めるために
 -(void)stopAcc { @try { if (acc) { acc.delegate = nil; acc = nil; [self resetState]; } } @catch (NSException *exception) { NSLog(@"stopAcc %@",exception); } } 

その後、加速度計の更新イベントのみをキャッチできます
 - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { @try { [filter addAcceleration:acceleration]; //    «»  double x = filter.x*kAccDataScale; //  double y = filter.y*kAccDataScale; if (startY == 100) { startY = acceleration.y*kAccDataScale; //     Y } //    X if (x > 1) { x = 1; } else if (x < -1) { x = -1; } //    Y if (y > 1) { y = 1; } else if (y < -1) { y = -1; } //    y = (y - startY); //   [self setOffsetElementForX:x Y:y]; } @catch (NSException *exception) { NSLog(@"accelerometer %@",exception); } } @end 

最後に、シフト関数では、異なるレイヤーを異なる固定量で移動します。 したがって、上部の要素は背景よりも低速で移動し、3D効果を生み出します。 この場合、すべての要素をデバイスの回転に向かって移動する必要があります。
 -(void)setOffsetElementForX:(double)x Y:(double)y { @try { allEll.transform = CGAffineTransformMakeTranslation(-8.5*x, 11.5*y); movingButtonsView.transform = CGAffineTransformMakeTranslation(-8.5*x, 11.5*y); arcView.transform = CGAffineTransformMakeTranslation(-8.5*x, 11.5*y); bgView.transform = CGAffineTransformMakeTranslation(-17*x, 23*y); bgStar1View.transform = CGAffineTransformMakeTranslation(-13*x, 18*y); bgStar2View.transform = CGAffineTransformMakeTranslation(-10*x, 13*y); allEll2.transform = CGAffineTransformMakeTranslation(-17*x, 21*y); } @catch (NSException *exception) { NSLog(@"offsetElementForX %@",exception); } } 

これらの4つの簡単なステップは、プログラムをより魅力的で、興味深く、革新的なものにします。 結局21世紀。 壮大でスタイリッシュなデザインは、レビュアーによるアプリケーションの評価にプラスの影響を与え、数十万の競合他社と区別できることを忘れないでください。 Lifeware Solutions(http://www.lifewaresolutions.com/)の私たちは積極的に研究に従事しており、私たちの経験があなたに役立つなら幸いです。 私はあなたのフィードバックにとても感謝しています。

Source: https://habr.com/ru/post/J162081/


All Articles