ホームページ ウェブフロントエンド jsチュートリアル WebGL は FBO を使用してキューブ マップ効果の完全な例を完成させます (デモ ソース コードのダウンロード付き)_JavaScript スキル

WebGL は FBO を使用してキューブ マップ効果の完全な例を完成させます (デモ ソース コードのダウンロード付き)_JavaScript スキル

May 16, 2016 pm 03:18 PM
webgl

この記事の例では、WebGL が FBO を使用してキューブ マップ効果を完成させる方法について説明します。参考のために皆さんと共有してください。詳細は次のとおりです:

この記事では主に WebGL の基本的なポイントを記録し、FBO と環境マップの使用方法も学びます。まずレンダリングを見てみましょう (WebGL、Chrome、Firefox、IE11 のサポートが必要です)。

主な実装プロセスは次のとおりです。まず、FBO を使用して現在の環境を立方体テクスチャに出力し、次に現在の立方体を描画し、最後にボールを描画し、FBO に関連付けられたテクスチャを球体に貼り付けます。

WebGL を開始するときは、OpenGL の基本を理解しておくことが最善です。以前に Obj の完全性と MD2 について話したときに、シェーダーの追加と使用により、OpenGL API のほとんどが使用されなくなったことに気づいたかもしれません。 WebGL のほとんどの関数は、主要な関数を完了するシェーダーです。WebGL の基本的な関数を理解するために、これまでの関数と比較してください。この記事では、比較的完全なフレームワークを使用していません。行列の計算を支援するためにフレームワーク (gl-matrix.js) が使用されています。

OpenGL を使用する場合と同様に、使用環境を初期化し、グローバルな使用法を抽出する必要があります。関連するコードは次のとおりです:

初期化:

var gl;//WebGLRenderingContext
var cubeVBO;//Cube buffer ID
var sphereVBO;//球体VBO
var sphereEBO;//球体EBO
var cubeTexID;//立方体纹理ID
var fboBuffer;//桢缓存对象
var glCubeProgram;//立方体着色器应用
var glSphereProgram;//球体着色器应用
var fboWidth = 512;//桢缓存绑定纹理宽度
var fboHeight = 512;//桢缓存绑定纹理高度
var targets;//立方体贴图六个方向
var pMatrix = mat4.create();//透视矩阵
var vMatrix = mat4.create();//视图矩阵
var eyePos = vec3.fromValues(0.0, 1.0, 0.0);//眼睛位置
var eyeLookat = vec3.fromValues(0.0, -0.0, 0.0);//眼睛方向
var spherePos = vec3.fromValues(0.0, -0.0, 0.0);//球体位置
var canvanName;
function webGLStart(cName) {
  canvanName = cName;
  InitWebGL();
  InitCubeShader();
  InitSphereShader();
  InitCubeBuffer();
  InitSphereBuffer();
  InitFBOCube();
  //RenderFBO();
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.enable(gl.DEPTH_TEST);
  tick();
}
function InitWebGL() {
  //var canvas = document.getElementById(canvanName);
  InitGL(canvanName);
}
function InitGL(canvas) {
  try {
    //WebGLRenderingContext 
    gl = canvas.getContext("experimental-webgl");
    gl.viewportWidth = canvas.width;
    gl.viewportHeight = canvas.height;
    targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X,
           gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
           gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
           gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
           gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
           gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];
  } catch (e) { }
  if (!gl) { alert("你的浏览器不支持WebGL"); }
}

ログイン後にコピー

ここでは、Web ページ内の WebGL の上位環境と下位環境を初期化し、一連の初期化処理を行います。部屋、つまりキューブに関連するコードは次のとおりです。

キューブ:

function InitCubeShader() {
  //WebGLShader
  var shader_vertex = GetShader("cubeshader-vs");
  var shader_fragment = GetShader("cubeshader-fs");
  //WebglCubeProgram
  glCubeProgram = gl.createProgram();
  gl.attachShader(glCubeProgram, shader_vertex);
  gl.attachShader(glCubeProgram, shader_fragment);
  gl.linkProgram(glCubeProgram);
  if (!gl.getProgramParameter(glCubeProgram, gl.LINK_STATUS)) {
    alert("Shader hava error.");
  }
  gl.useProgram(glCubeProgram);
  glCubeProgram.positionAttribute = gl.getAttribLocation(glCubeProgram, "a_position");
  glCubeProgram.normalAttribute = gl.getAttribLocation(glCubeProgram, "a_normal");
  glCubeProgram.texCoordAttribute = gl.getAttribLocation(glCubeProgram, "a_texCoord");
  glCubeProgram.view = gl.getUniformLocation(glCubeProgram, "view");
  glCubeProgram.perspective = gl.getUniformLocation(glCubeProgram, "perspective");
}
function InitCubeBuffer() {
  var cubeData = [
      -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0,
      -10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 1.0,
      10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0,
      10.0, 10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 1.0,
      10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 0.0, 0.0,
      -10.0, -10.0, -10.0, 0.0, 0.0, -10.0, 1.0, 0.0,
      -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0,
      10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 0.0,
      10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0,
      10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 1.0, 1.0,
      -10.0, 10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 1.0,
      -10.0, -10.0, 10.0, 0.0, 0.0, 10.0, 0.0, 0.0,
      -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0,
      10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 1.0, 0.0,
      10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0,
      10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 1.0, 1.0,
      -10.0, -10.0, 10.0, 0.0, -10.0, 0.0, 0.0, 1.0,
      -10.0, -10.0, -10.0, 0.0, -10.0, 0.0, 0.0, 0.0,
      10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0,
      10.0, 10.0, -10.0, 10.0, 0.0, 0.0, 1.0, 0.0,
      10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0,
      10.0, 10.0, 10.0, 10.0, 0.0, 0.0, 1.0, 1.0,
      10.0, -10.0, 10.0, 10.0, 0.0, 0.0, 0.0, 1.0,
      10.0, -10.0, -10.0, 10.0, 0.0, 0.0, 0.0, 0.0,
      10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0,
      -10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 1.0, 0.0,
      -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0,
      -10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 1.0, 1.0,
      10.0, 10.0, 10.0, 0.0, 10.0, 0.0, 0.0, 1.0,
      10.0, 10.0, -10.0, 0.0, 10.0, 0.0, 0.0, 0.0,
      -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0,
      -10.0, -10.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0,
      -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0,
      -10.0, -10.0, 10.0, -10.0, 0.0, 0.0, 1.0, 1.0,
      -10.0, 10.0, 10.0, -10.0, 0.0, 0.0, 0.0, 1.0,
      -10.0, 10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0,
  ];
  cubeVBO = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cubeData), gl.STATIC_DRAW);
}
function RenderCube() {
  gl.useProgram(glCubeProgram);
  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVBO);
  gl.vertexAttribPointer(glCubeProgram.positionAttribute, 3, gl.FLOAT, false, 32, 0);
  gl.enableVertexAttribArray(glCubeProgram.positionAttribute);
  gl.vertexAttribPointer(glCubeProgram.normalAttribute, 3, gl.FLOAT, false, 32, 12);
  gl.enableVertexAttribArray(glCubeProgram.normalAttribute);
  gl.vertexAttribPointer(glCubeProgram.texCoordAttribute, 2, gl.FLOAT, false, 32, 24);
  gl.enableVertexAttribArray(glCubeProgram.texCoordAttribute);
  gl.uniformMatrix4fv(glCubeProgram.view, false, vMatrix);
  gl.uniformMatrix4fv(glCubeProgram.perspective, false, pMatrix);
  gl.drawArrays(gl.TRIANGLES, 0, 36);
}

ログイン後にコピー

上記のコードは主に、キューブのシェーダー オブジェクトの初期化、関連するキャッシュの初期化、およびキューブの描画に分かれています。OpenGL でシェーダーを使用して描画する場合、プロセスは同様であると言えます。 Opengl には固定パイプラインがありません。InterleavedArrays などの一部の関数は頂点、法線、テクスチャを指定するために使用され、vertexAttribPointer はアプリケーションとシェーダーの間でデータを転送するために使用されます。以前の MD2 フレーム アニメーション実装におけるパラメータ転送の改良版には、関連するアプリケーションもあります。

キューブシェーダーに対応するメインコードは次のとおりです:

キューブ シェーダーの実装:

<script id="cubeshader-fs" type="x-shader/x-fragment">
    precision mediump float;
    varying vec3 normal;
    varying vec3 tex1;
    varying vec3 tex2;
    void main( void )
    {
    float x = tex1.x * 6.28 * 8.0; //2兀 * 8
    float y = tex1.y * 6.28 * 8.0; //2兀 * 8
    //cos(x)= 8个 (1 -1 1)
    gl_FragColor = vec4(tex2,1.0) * vec4(sign(cos(x)+cos(y))); //
    //gl_FragColor = vec4(normal*vec3(0.5)+vec3(0.5), 1);
    }
</script>
<script id="cubeshader-vs" type="x-shader/x-vertex">
    attribute vec3 a_position;
    attribute vec3 a_normal;
    attribute vec2 a_texCoord;
    uniform mat4 view;
    uniform mat4 perspective;
    varying vec3 normal;
    varying vec3 tex1;
    varying vec3 tex2;
    void main( void )
    {
    gl_Position = perspective * view * vec4(a_position,1.0);
    normal = a_normal;
    tex1 = vec3(a_texCoord,0.0);
    tex2 = normalize(a_position)*0.5+0.5;
    }
</script>

ログイン後にコピー

シェーダーには、呼び出す ftransform() 関数がありません。モデル、ビュー、およびパースペクティブ マトリックスを自分で渡す必要があります。ここでは、モデルは原点を中心として描画されます。これは、モデル ビュー マトリックスを意味します。はビュー マトリックスでもあるため、画面位置の計算にはビュー マトリックスとパースペクティブ マトリックスのみが必要です。フラグメント シェーダーでは、頂点シェーダーのテクスチャ座標から x と y が渡され、対応するプロセスは 8 360 度に相当する 6.28*8.0 であり、立方体上のブロックの表示を制御するために使用されます。頂点マッピング [0,1] の値は、立方体の 6 つの側面にそれぞれ異なる意味を設定し、2 つのベクトルの積を使用して 2 つのカラー表示を混合します (gl_FragColor = vec4(tex2,1.0))。 * vec4(sign( cos(x)+cos(y)))。

球を表示する前に、まず現在の環境の立方体描画を生成します。まずフレームキャッシュと立方体描画を生成し、原点を中心に描画します。それぞれ下、左、前、右を使用して、フレーム バッファーを立方体の 6 つの面にそれぞれ出力します。 主なコードは次のとおりです。

FBO とキューブ テクスチャ:

function InitFBOCube() {
  // WebGLFramebuffer
  fboBuffer = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fboBuffer);
  fboBuffer.width = 512;
  fboBuffer.height = 512;
  cubeTexID = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexID);
  gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  for (var i = 0; i < targets.length; i++) {
    gl.texImage2D(targets[i], 0, gl.RGBA, fboBuffer.width, fboBuffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
  }
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
function RenderFBO() {
  gl.disable(gl.DEPTH_TEST);
  gl.viewport(0, 0, fboBuffer.width, fboBuffer.height);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.bindFramebuffer(gl.FRAMEBUFFER, fboBuffer);
  for (var i = 0; i < targets.length; i++) {
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[i], cubeTexID, null);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  }
  mat4.perspective(pMatrix, 45, fboBuffer.width / fboBuffer.height, 0.1, 100.0);
  for (var i = 0; i < targets.length; i++) {
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, targets[i], cubeTexID, null);
    var lookat = vec3.create();
    var up = vec3.create();
    up[1] = 1.0;
    if (i == 0) {
      lookat[0] = -1.0;
    } else if (i == 1) {
      lookat[0] = 1.0;      
    } else if (i == 2) {
      lookat[1] = -1.0;
      up[0] = 1.0;
    } else if (i == 3) {
      lookat[1] = 1.0;
      up[0] = 1.0;
    } else if (i == 4) {
      lookat[2] == -1.0;      
    } else if (i == 5) {
      lookat[2] = 1.0;      
    } else {     
    }
    //vec3.fromValues(0.0, 0.0, 0.0)
    vMatrix = mat4.create();
    mat4.lookAt(vMatrix, vec3.fromValues(0.0, 0.0, 0.0), lookat, up);
    //mat4.scale(vMatrix, vMatrix, vec3.fromValues(-1.0, -1.0, -1.0));
    //mat4.translate(vMatrix, vMatrix, spherePos);    
    RenderCube();
  }
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.enable(gl.DEPTH_TEST);
}

ログイン後にコピー
上記の gl-matrix が提供するマトリックス アルゴリズムに問題があるのか​​、それともこのようになっている必要があるのか​​はわかりません。上下に移動するときに生成されるテクスチャ マップが間違っており、その上向きのベクトルが間違っています。カメラの向きを変える必要があります。カメラ位置がターゲットの生成された Z 軸と設定された UP 軸に平行であるため、X 軸を正しく計算できず、対応する UP 軸も計算できず、対応するビュー マトリックスにエラーが発生します。

最後のステップは球を描画することです。コードは主に立方体のものと似ていますが、球の頂点アルゴリズムに注目してください。

球体:

function InitSphereShader() {
  //WebGLShader
  var shader_vertex = GetShader("sphereshader-vs");
  var shader_fragment = GetShader("sphereshader-fs");
  //WebglCubeProgram
  glSphereProgram = gl.createProgram();
  gl.attachShader(glSphereProgram, shader_vertex);
  gl.attachShader(glSphereProgram, shader_fragment);
  gl.linkProgram(glSphereProgram);
  if (!gl.getProgramParameter(glSphereProgram, gl.LINK_STATUS)) {
    alert("Shader hava error.");
  }
  glSphereProgram.positionAttribute = gl.getAttribLocation(glSphereProgram, "a_position");
  glSphereProgram.normalAttribute = gl.getAttribLocation(glSphereProgram, "a_normal");
  glSphereProgram.eye = gl.getUniformLocation(glSphereProgram, "eye");
  glSphereProgram.mapCube = gl.getUniformLocation(glSphereProgram, "mapCube");
  glSphereProgram.model = gl.getUniformLocation(glSphereProgram, "model");
  glSphereProgram.view = gl.getUniformLocation(glSphereProgram, "view");
  glSphereProgram.perspective = gl.getUniformLocation(glSphereProgram, "perspective");
}
function InitSphereBuffer() {
  var radius = 1;
  var segments = 16;
  var rings = 16;
  var length = segments * rings * 6;
  var sphereData = new Array();
  var sphereIndex = new Array();
  for (var y = 0; y < rings; y++) {
    var phi = (y / (rings - 1)) * Math.PI;
    for (var x = 0; x < segments; x++) {
      var theta = (x / (segments - 1)) * 2 * Math.PI;
      sphereData.push(radius * Math.sin(phi) * Math.cos(theta));
      sphereData.push(radius * Math.cos(phi));
      sphereData.push(radius * Math.sin(phi) * Math.sin(theta));
      sphereData.push(Math.sin(phi) * Math.cos(theta));
      sphereData.push(radius * Math.cos(phi))
      sphereData.push(Math.sin(phi) * Math.sin(theta));
    }
  }
  for (var y = 0; y < rings - 1; y++) {
    for (var x = 0; x < segments - 1; x++) {
      sphereIndex.push((y + 0) * segments + x);
      sphereIndex.push((y + 1) * segments + x);
      sphereIndex.push((y + 1) * segments + x + 1);
      sphereIndex.push((y + 1) * segments + x + 1);
      sphereIndex.push((y + 0) * segments + x + 1)
      sphereIndex.push((y + 0) * segments + x);
    }
  }
  sphereVBO = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereData), gl.STATIC_DRAW);
  sphereVBO.numItems = segments * rings;
  sphereEBO = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO);
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(sphereIndex), gl.STATIC_DRAW);
  sphereEBO.numItems = sphereIndex.length;
}
function RenderSphere() {
  gl.useProgram(glSphereProgram);
  gl.bindBuffer(gl.ARRAY_BUFFER, sphereVBO);
  gl.vertexAttribPointer(glSphereProgram.positionAttribute, 3, gl.FLOAT, false, 24, 0);
  gl.enableVertexAttribArray(glSphereProgram.positionAttribute);
  gl.vertexAttribPointer(glSphereProgram.normalAttribute, 3, gl.FLOAT, false, 24, 12);
  gl.enableVertexAttribArray(glSphereProgram.normalAttribute);
  var mMatrix = mat4.create();
  mat4.translate(mMatrix, mMatrix, spherePos);
  gl.uniform3f(glSphereProgram.eye, eyePos[0],eyePos[1],eyePos[2]);
  gl.uniformMatrix4fv(glSphereProgram.model, false, mMatrix);
  gl.uniformMatrix4fv(glSphereProgram.view, false, vMatrix);
  gl.uniformMatrix4fv(glSphereProgram.perspective, false, pMatrix);
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeTexID);
  //gl.uniformMatrix4fv(glSphereProgram.mapCube, 0);
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphereEBO);
  gl.drawElements(gl.TRIANGLES, sphereEBO.numItems, gl.UNSIGNED_SHORT, 0);
  gl.bindTexture(gl.TEXTURE_2D, null);
}

ログイン後にコピー
ご覧のとおり、立方体と同じ、シェーダーの初期化、頂点と法線の初期化、描画の 3 つのステップです。シェーダー コードは以下のとおりです:

球体シェーダー:

<script id="sphereshader-fs" type="x-shader/x-fragment">
    precision mediump float;
    varying vec3 normal;
    varying vec3 eyevec;
    uniform samplerCube mapCube;
    void main( void )
    {
    gl_FragColor = textureCube(mapCube, reflect(normalize(-eyevec), normalize(normal)));
    }
</script>
<script id="sphereshader-vs" type="x-shader/x-vertex">
    attribute vec3 a_position;
    attribute vec3 a_normal;
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 perspective;
    uniform vec3 eye;
    varying vec3 normal;
    varying vec3 eyevec;
    void main( void )
    {
    gl_Position = perspective * view * model * vec4(a_position,1.0);
    eyevec = -eye;// a_position.xyz;
    normal = a_normal;
    }
</script>

ログイン後にコピー
前の立方体と少し異なるのは、球体が独自のモデル マトリックスを持っていることです。これも通常の使用法であり、球体の頂点ベクトルと法線に対応する目がフラグメント シェーダーに渡されます。これは便利です。以前に生成された立方体テクスチャに対して、目が頂点を通過する点に基づいて現在の球に対応する環境カラーを取得し、対応する法線ベクトルを立方体テクスチャに反映します。ここでは、textureCube を直接呼び出すことができます。上記のプロセスを完了するには、手動で計算する必要はありません。

GetShader 関数の使用方法については、こちらの説明を参照してください

http://msdn.microsoft.com/zh-TW/library/ie/dn302360(v=vs.85)

上記のメインの描画関数は完了したと言えますが、私たちの描画関数はアクティブであるため、クライアント環境がどのくらいの頻度で描画されるかをシミュレートする必要があります。メインのコードは次のとおりです:

アニメーション:

function tick() {
  Update();
  OnDraw();
  setTimeout(function () { tick() }, 15);
}
function OnDraw() {
  //fbo rander CUBE_MAP
  RenderFBO();
  //element rander
  gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 200.0);
  mat4.lookAt(vMatrix, eyePos, eyeLookat, vec3.fromValues(0.0, 1.0, 0.0));
  RenderCube();
  RenderSphere();
}
var lastTime = new Date().getTime();
function Update() {
  var timeNow = new Date().getTime();
  if (lastTime != 0) {
    var elapsed = timeNow - lastTime;
    //3000控制人眼的旋转速度。8控制人眼的远近
    eyePos[0] = Math.cos(elapsed / 3000) * 8;
    eyePos[2] = Math.sin(elapsed / 2000) * 8;
    spherePos[0] = Math.cos(elapsed / 4000) * 3;
    spherePos[2] = Math.cos(elapsed / 4000) * 3;
  }
}

ログイン後にコピー

上記では、Update 関数と Draw 関数が 15 ミリ秒ごとに呼び出されます。Update 関数は目と球の位置を更新するために使用され、Draw 関数はペイントに使用されます。

完全なサンプルコードについては、ここをクリックしてくださいこのサイトからダウンロードしてください

JS 特殊効果に関連するさらなるコンテンツに興味のある読者は、このサイトの特別トピック「jQuery アニメーションと特殊効果の使用法の概要」および「一般的な古典の概要」をチェックしてください。 jQuery"

の特殊効果

この記事が JavaScript プログラミングのすべての人に役立つことを願っています。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptの文字列文字を交換します JavaScriptの文字列文字を交換します Mar 11, 2025 am 12:07 AM

JavaScript文字列置換法とFAQの詳細な説明 この記事では、javaScriptの文字列文字を置き換える2つの方法について説明します:内部JavaScriptコードとWebページの内部HTML。 JavaScriptコード内の文字列を交換します 最も直接的な方法は、置換()メソッドを使用することです。 str = str.replace( "find"、 "置換"); この方法は、最初の一致のみを置き換えます。すべての一致を置き換えるには、正規表現を使用して、グローバルフラグGを追加します。 str = str.replace(/fi

8見事なjQueryページレイアウトプラグイン 8見事なjQueryページレイアウトプラグイン Mar 06, 2025 am 12:48 AM

楽なWebページレイアウトのためにjQueryを活用する:8本質的なプラグイン jQueryは、Webページのレイアウトを大幅に簡素化します。 この記事では、プロセスを合理化する8つの強力なjQueryプラグイン、特に手動のウェブサイトの作成に役立ちます

独自のAjax Webアプリケーションを構築します 独自のAjax Webアプリケーションを構築します Mar 09, 2025 am 12:11 AM

それで、あなたはここで、Ajaxと呼ばれるこのことについてすべてを学ぶ準備ができています。しかし、それは正確には何ですか? Ajaxという用語は、動的でインタラクティブなWebコンテンツを作成するために使用されるテクノロジーのゆるいグループ化を指します。 Ajaxという用語は、もともとJesse Jによって造られました

10 jQueryの楽しみとゲームプラグイン 10 jQueryの楽しみとゲームプラグイン Mar 08, 2025 am 12:42 AM

10の楽しいjQueryゲームプラグインして、あなたのウェブサイトをより魅力的にし、ユーザーの粘着性を高めます! Flashは依然としてカジュアルなWebゲームを開発するのに最適なソフトウェアですが、jQueryは驚くべき効果を生み出すこともできます。また、純粋なアクションフラッシュゲームに匹敵するものではありませんが、場合によってはブラウザで予期せぬ楽しみもできます。 jquery tic toeゲーム ゲームプログラミングの「Hello World」には、JQueryバージョンがあります。 ソースコード jQueryクレイジーワードコンポジションゲーム これは空白のゲームであり、単語の文脈を知らないために奇妙な結果を生み出すことができます。 ソースコード jquery鉱山の掃引ゲーム

独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? 独自のJavaScriptライブラリを作成および公開するにはどうすればよいですか? Mar 18, 2025 pm 03:12 PM

記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

jQuery Parallaxチュートリアル - アニメーションヘッダーの背景 jQuery Parallaxチュートリアル - アニメーションヘッダーの背景 Mar 08, 2025 am 12:39 AM

このチュートリアルでは、jQueryを使用して魅惑的な視差の背景効果を作成する方法を示しています。 見事な視覚的な深さを作成するレイヤー画像を備えたヘッダーバナーを構築します。 更新されたプラグインは、jQuery 1.6.4以降で動作します。 ダウンロードしてください

Ajaxを使用して動的にボックスコンテンツをロードします Ajaxを使用して動的にボックスコンテンツをロードします Mar 06, 2025 am 01:07 AM

このチュートリアルでは、Ajaxを介してロードされた動的なページボックスの作成を示しており、フルページのリロードなしでインスタントリフレッシュを可能にします。 JQueryとJavaScriptを活用します。カスタムのFacebookスタイルのコンテンツボックスローダーと考えてください。 重要な概念: ajaxとjquery

JavaScript用のクッキーレスセッションライブラリを作成する方法 JavaScript用のクッキーレスセッションライブラリを作成する方法 Mar 06, 2025 am 01:18 AM

このJavaScriptライブラリは、Cookieに依存せずにセッションデータを管理するためにWindow.nameプロパティを活用します。 ブラウザ全体でセッション変数を保存および取得するための堅牢なソリューションを提供します。 ライブラリは、セッションの3つのコア方法を提供します

See all articles