ダブルキャッシュを使用したCanvas clearRectによるスプラッシュスクリーンの問題を解決しました。
前置き
今日、H5でcanvasを使った作業をしていて、スプラッシュスクリーンの問題に遭遇しました。チカチカするのは以下のような感じです。
イシュー・ブリーフ
機能プロファイル
H5 この部分の機能は、副次的なメニューをクリックすることで、画像のマスクを切り替えたり、背景を変更したりすることです。
機能がシンプルなため、この機能の実装にはネイティブキャンバスを使用しました。ただし
//n=1e9 simulate map
map<int,int> mp;//1e9 occurs at most 1e9 times
int main()
{
IO;
int n,cnt=0;//cnt at most 1e9
cin>>n;
//1098
mp[n]++;
cnt++;
while(n)
{
n++;
while(n%10==0)
n=n/10;
if(mp[n])
break;
mp[n]++;
cnt++;
}
cout<<cnt<<endl;
return 0;
}
を使用してキャンバスをクリアすると、ちらつきが発生します。
コードの実装(問題コード)
以下のコードは、スプラッシュ画面を表示するためのキーコードで、onloadによる画像の定義は省略されています。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const ll inf=0x3f3f3f3f3f3f3f3f3f;
const int INF=0x3f3f3f3f3f;
const ll mod=1e9+7;
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
ll gcd(ll a,ll b)
{
return b!=0?gcd(b,a%b):a;
}
char a[9];
int main()
{
IO;
int n,f=0;
string s;
cin>>n;
cin>>s;
for(int i=1;i<=9;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
if(s[i]<a[s[i]-'0'])//guarantee that the change is to the highest bit
{
s[i]=a[s[i]-'0'];
f=1;//see how long the interval can be continuous
}
else if(f==1 && s[i]>a[s[i]-'0'])//can't just start when s[i] is big no need to replace this valuable once still useless break off
{ // unless it has been modified this time can not be modified
break;
}
}
cout<<s<<endl;
return 0;
}
課題分析
簡単な解析の結果、スプラッシュスクリーンが発生する原因は
queue<char> q;
int a[maxn];
int main()
{
IO;
int n,f=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int l=1,r=n,temp=0,cnt=0;
while(n--)
{
if(a[l]>temp && a[r]>temp)
{
if(a[l]<a[r])
{
temp=a[l];
cnt++;
l++;
q.push('L');
}
else
{
temp=a[r];
cnt++;
r--;
q.push('R');
}
}
else if(a[l]>temp)
{
temp=a[l];
cnt++;
l++;
q.push('L');
}
else if(a[r]>temp)
{
temp=a[r];
cnt++;
r--;
q.push('R');
}
else
break;
}
cout<<cnt<<endl;
while(!q.empty())
{
cout<<q.front();
q.pop();
}
cout<<endl;
return 0;
}
キャンバスをクリアした後、描画に時間がかかるためスプラッシュスクリーンが発生します。
ダブルキャッシングとは
を見てみましょう。 マイクロソフト サイト内 ダブルバッファードグラフィックス ダブルキャッシュについて解説しています。
グラフィックのプログラミングを行う際、フリッカーが発生することはよくある問題です。複数の複雑な描画操作を必要とするグラフィックス操作では、レンダリングされた画像がちらついたり、許容できない外観になったりすることがあります。これらの問題に対処するため、.NET Frameworkはダブルキャッシュを提供しています。
ダブルバッファリングは、コンテンツバッファリングを使用して、複数の描画操作に関連するフリッカーの問題に対処します。ダブルバッファリングが有効な場合、すべての描画操作は、まず、画面上の描画面ではなく、メモリキャッシュにレンダリングされます。すべての描画操作が完了すると、メモリバッファはそれに関連する描画面に直接コピーされます。画面上では1つの描画操作しか行われないため、複雑な描画操作に伴う画像のちらつきをなくすことができる。
<スパン デュアルキャッシュの問題点を解決
上記の引用ですが、要するに、描画時間が長いためにスプラッシュ画面が発生することが一番の問題で、その解決策として、キャンバスを キャッシュキャンバス を介して渡される キャンバスをキャッシュする を描画し、描画が完了したら直接 キャンバスをキャッシュする を元のキャンバスに貼り付けることで、描画時間が長いために起こるスプラッシュスクリーンの問題を解決しています。
コードの実装
以下のコードは、画像の定義とonloadを省略した、キーコードです。
updateCanvas(){
const canvas = document.getElementById('canvas'); // Get the canvas in the page
const ctx = canvas.getContext('2d');
const tempCanvas = document.createElement('canvas'); // create a new canvas as a cache canvas
const tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = 1448; tempCanvas.height = 750; // set the width and height
// Start drawing
tempCtx.drawImage(bg,0,0); // background
... // omit the rest of the drawing process
// cache the canvas to finish drawing
ctx.clearRect(0,0,1448,750); // Clear the old canvas
ctx.drawImage(tempCanvas,0,0); // copy the cached canvas to the old one
}
効果の受容
スプラッシュスクリーンの問題が解決されたことがよくわかりますね!
概要
キャンバスの再描画時に
clearRect
を使用してキャンバスをクリアします。この時点ではキャンバスは空ですが、再描画を開始した後、コンテンツが増えるとそれに伴って時間が長くなるため、視覚的なギャップが生じ、スプラッシュ画面が表示されることになります。
スプラッシュスクリーンを解決することで、本当に描画時間が長くなる問題を解決する方法です。
のグラフィックス画像処理プログラミングを紹介します。 ダブルキャッシング の概念に基づき、描画処理は キャッシュ・キャンバス というように、ページ上のキャンバスが描画処理から排除され キャンバスをキャッシュする が追加されないので、描画処理が見られず、スプラッシュスクリーンの問題が解決されます。
今回の記事は以上です。皆さんの勉強のお役に立てれば幸いです。そして、スクリプトハウスを応援していただければ幸いです。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
html5でポップアップ画像のクリック機能を実装する
-
フロントエンドのHtml5でスクリーンショットを共有する方法のサンプルコード
-
HTML5ページの要素と属性の分析
-
モバイルHTML5入力に関するFAQ(要約)
-
Canvasでグラフィックス/イメージバインディングのイベントリスナーを実装する方法
-
シェアボタン付きAmazeUIボトムナビゲーションバー用サンプルコード
-
Html5は、コンテナは、画面の高さや残りの高さの適応的なレイアウトの実装を埋めることができます
-
canvas.toDataURL()エラーの詳細な解決策はすべてこちら
-
9ボックスグリッドの原則を用いたHTMLページレイアウト
-
キャンバスを使ってWeChatアバターなしの招待状ポスターを生成する