import { BufferGeometry, Vector2, Material, ShaderMaterial, Object3D, Shader, Vector4 } from "three";
import { Viewport } from "../helper";
import { MeshUI } from "../component/mesh-ui";
import { Texes } from "../component/loader";
import { Transition } from "../component/transition";
export type Uniforms = ShaderMaterial["uniforms"];
type Defines = ShaderMaterial["defines"];
export type VertexShader = ShaderMaterial["vertexShader"];
export type FragmentShader = ShaderMaterial["fragmentShader"];
/**
 * Obクラスで作成した[ShaderMaterial](https://threejs.org/docs/#api/en/materials/ShaderMaterial)に設定される{@link Ob.uniforms}のデフォルト値です。
 */
export type DefaultUniforms = {
    /**
     * requestAnimationFrame のループ毎にカウントアップされた整数値が自動的に設定されます。
     */
    uTick: {
        value: number;
    };
    /**
     * メッシュ上のマウス位置がuv座標で自動的に設定されます。
     * 使用する場合は [data-interactive](/reference/html/#data-interactive) を付与してください。
     */
    uMouse: {
        value: Vector2;
    };
    /**
     * メッシュにホバーしている時は1、それ以外は0が自動的に設定されます。
     * 使用する場合は [data-interactive](/reference/html/#data-interactive) を付与してください。
     */
    uHover: {
        value: number;
    };
    /**
     * アニメーション用のUniformです。neglが自動的に値が更新されることはありませんので、自身でアニメーションを定義する際のUniformとして利用してください。一般的には0 ~ 1の範囲でアニメーションの進捗を表します。
     */
    uProgress: {
        value: number;
    };
    /**
     * 透明度を渡すためのUniformです。neglが自動的に値が更新されることはありませんので、各自で透明度を変更する際のUniformとして利用してください。
     */
    uAlpha: {
        value: number;
    };
    /**
     * 画像とDOM要素のアスペクト比から算出した値を保持します。
     */
    uResolution: {
        value: Vector4;
    };
};
/**
 * Obクラスのコンストラクタの引数の型です。
 */
export type ObConstructorArgs = {
    texes: Texes;
    el: HTMLElement;
    type: string;
};
/**
 * Obクラスはエフェクト制御を行うクラスです。
 * エフェクト（three.jsで言うところのメッシュ）を作成する際はObクラスを継承して作成してください。Obクラスを継承することで、画面スクロール、画面リサイズ、画像のアスペクト比調整、マウスクリックによるイベント発火等が簡単に実装できるようになります。Obクラスは応用編で作成したものを拡張した形になりますので、Obクラスの基本的な使用方法は[応用編](https://not-equal.teachable.com/courses/enrolled/2076384)を参照してください。
 *
 * **Obクラスの使用例は[エフェクト](/sample/single/)を参照してください。**
 *
 * ### 例外的なメッシュの追加方法
 * 基本的にはObクラスを継承してエフェクトは作成しますが、スクロール制御や画面のリサイズ制御が必要ない場合はメッシュやライトをthree.jsのシーンに直接挿入することも出来ます。ただ、直接シーンに追加されたメッシュに関してはneglは制御を行いませんので、独自で制御する必要があります。
 *
 * **Obを使わずに直接シーンにメッシュやライトを追加**
 * ```js
 * // メッシュをObを使わずに作成
 * const material = new MeshBasicMaterial({ color: "#ff0000" });
 * const geometry = new PlaneGeometry(500, 500);
 * const mesh = new Mesh(material, geometry);
 *
 * // ライトの作成
 * const ambientLight = new AmbientLight("#ffffff", 0.3);
 *
 * // メッシュとライトをシーンに追加
 * // * world.sceneが画面に表示されているシーンとなるため、このシーンに追加すると画面に表示されます。
 * world.scene.add(mesh, ambientLight);
 * // このようにしてシーンに追加されたエフェクトにはリサイズ制御などは効きません。
 * ```
 */
export declare class Ob {
    [method: string]: any;
    /**
     * DOM要素を保持するためのプロパティです。
     * $.elにはエフェクトが紐づくDOM要素が格納されます。
     */
    $: {
        el: HTMLElement;
        [key: string]: HTMLElement | HTMLElement[];
    };
    /**
     * trueの時、キャッシュから取得されたオブジェクト。falseの時、それ以外。
     */
    isCache: boolean;
    /**
     * テクスチャマップ
     */
    texes: Texes;
    /**
     * DOM要素のdataset（data-*のキーと値が格納されているオブジェクト）のコピーを保持します。
     */
    dataAttrs: {
        [key: string]: string | undefined;
    };
    /**
     * メッシュのスケールを保持します。これは画面の初期表示時からどれだけメッシュが伸縮しているかを数値で保持します。メッシュのスケールを変更した際はこのプロパティの値も変更してください。
     */
    scale: {
        width: number;
        height: number;
        depth: number;
    };
    /**
     * リサイズフラグ
     * リサイズ処理を実行中は `true`、それ以外 `false`。
     */
    resizing: boolean;
    /**
     * fixed フラグ
     * `true` スクロールによるエフェクトの追従を自動で行います。`false`、スクロールに追従しません。
     */
    fixed: boolean;
    /**
     * $.el プロパティに格納されたDOM要素の [DOMRect](https://developer.mozilla.org/ja/docs/Web/API/DOMRect) の状態を保持します。画面幅が更新されるたびに最新の DOMRect で更新されます。
     */
    rect: DOMRect;
    /**
     * $.elプロパティに格納されたDOM要素のの画面初期表示時の [DOMRect](https://developer.mozilla.org/ja/docs/Web/API/DOMRect) を保持します。
     */
    originalRect: DOMRect;
    /**
     * {@link https://threejs.org/docs/?q=ShaderMa#api/en/materials/ShaderMaterial.defines ShaderMaterial#defines}オブジェクト
     * {@link setupDefines} の戻り値が設定されます。
     */
    defines: Defines;
    /**
     * {@link https://threejs.org/docs/?q=ShaderMa#api/en/materials/ShaderMaterial.uniforms ShaderMaterial#uniforms}オブジェクト
     * {@link setupUniforms} の戻り値が設定されます。
     */
    uniforms: Uniforms;
    /**
     * {@link https://threejs.org/docs/?q=ShaderMa#api/en/materials/ShaderMaterial.vertexShader ShaderMaterial#vertexShader}文字列
     * {@link setupVertex} の戻り値が設定されます。
     */
    vertexShader: VertexShader;
    /**
     * {@link https://threejs.org/docs/?q=ShaderMa#api/en/materials/ShaderMaterial.fragmentShader ShaderMaterial#fragmentShader}文字列
     * {@link setupFragment} の戻り値が設定されます。
     */
    fragmentShader: FragmentShader;
    /**
     * {@link https://threejs.org/docs/?q=Material#api/en/materials/Material Material}オブジェクト
     * {@link setupMaterial} の戻り値が設定されます。
     *
     */
    material: Material;
    /**
     * {@link https://threejs.org/docs/?q=BufferGeometry#api/en/core/BufferGeometry Geometry}オブジェクト
     * {@link setupGeometry} の戻り値が設定されます。
     */
    geometry: BufferGeometry;
    /**
     * {@link https://threejs.org/docs/?q=Object#api/en/core/Object3D Mesh}オブジェクト
     * {@link setupMesh} の戻り値が設定されます。
     */
    mesh: Object3D;
    /**
     * マウスホバー中の{@link https://threejs.org/docs/?q=Object#api/en/core/Object3D Mesh}オブジェクト
     */
    hoveringMesh?: Object3D;
    /**
     * 現在のスクロール位置をワールド座標で保持します。
     * * 横方向のスクロールは現状対応していません。
     */
    scrollPos: {
        x: number;
        y: number;
    };
    /**
     * Obクラスの初期化用静的メソッドです。
     *
     * Obクラス内で使用するテクスチャはtexesの変数としてObクラスのコンストラクタに渡していますが、テクスチャの取得は非同期処理トなるため、コンストラクタ関数内に記述することは出来ません。その為、この静的メソッド内でOb内で使用するテクスチャを取得し、インスタンス化を行っています。Obクラスのinit関数の実装は以下の通りです。
     *
     * ```ts
     * static async init({ el, type }: { el: HTMLElement; type: string }): Promise<Ob> {
     *  const texes = await loader.getTexByElement(el); // テスクチャを取得
     *  const o = new this({ texes, el, type });        // インスタンス化
     *  return o;                                       // インスタンスを返却
     * }
     * ```
     *
     */
    static init({ el, type, }: {
        el: HTMLElement;
        type: string;
    }): Promise<Ob>;
    constructor({ texes, el, type }: ObConstructorArgs);
    /**
     * メッシュの作成前に実行する処理を記載します。
     */
    beforeCreateMesh(): void;
    /**
     * 戻り値が ShaderMaterial.define に使用されます。
     *
     * 初期状態ではPIを返却します。
     * ```js
     * { PI: Math.PI }
     * ```
     * @returns
     */
    setupDefines(): Defines;
    /**
     * 戻り値がShaderMaterial.uniformsに使用されます。
     * 初期状態では {@link DefaultUniforms} が返却されます。
     * @returns
     */
    setupUniforms(): Uniforms;
    /**
     * ShaderMaterialの uniforms に設定する値を返却します。（テクスチャ用）
     * @param uniforms
     * @returns
     */
    setupTexes(uniforms: Uniforms): Uniforms;
    /**
     * ジオメトリを返却します。
     * 初期状態ではPlaneGeometryを返却します。
     *
     * ```js
     * new PlaneGeometry(this.rect.width, this.rect.height, 1, 1);
     * ```
     */
    setupGeometry(): BufferGeometry;
    /**
     * マテリアルを返却します。
     * 初期状態では ShaderMaterial を返却します。
     *
     * ```js
     * const material = new ShaderMaterial({
     * defines: this.defines,
     *   vertexShader: this.vertexShader,
     *   fragmentShader: this.fragmentShader,
     *   uniforms: this.uniforms,
     *   transparent: true,
     * });
     * material.onBeforeCompile = this.onBeforeCompile;
     * return material;
     * ```
     */
    setupMaterial(): Material;
    /**
     * シェーダのコンパイル前にシェーダコードを変更します。
     * Obクラスではシェーダの texture を texture2D に変換する以下のコードを記述しています。
     *
     * ```ts
      if (shader.isWebGL2) return; // WebGL 2.0の場合、変更は不要
  
      // WebGL1.0の場合はtexture関数が見つからないため、texture2Dにシェーダのコードを置換
      shader.vertexShader = shader.vertexShader.replace(/texture\(/g, "texture2D(");
      shader.fragmentShader = shader.fragmentShader.replace(/texture\(/g, "texture2D(");
     * ```
     */
    onBeforeCompile(shader: Shader): void;
    /**
     * ShaderMaterialに設定するVertexShaderシェーダを返却します。
     * オーバーライドして使用してください。シェーダを使用しないマテリアル（例えば、MeshStandardMaterial）の場合は空のメソッドでオーバーライドしてください。
     *
     * **シェーダを使わない場合は何も返却しないメソッドを定義してください。**
     * ```js
     * setupVertex(): FragmentShader {
     *  return;
     * }
     * ```
     */
    setupVertex(): VertexShader;
    /**
     * ShaderMaterialに設定するfragmentシェーダを返却します。
     * オーバーライドして使用してください。シェーダを使用しないマテリアル（例えば、MeshStandardMaterial）の場合は空のメソッドでオーバーライドしてください。
     *
     * **シェーダを使わない場合は何も返却しないメソッドを定義してください。**
     * ```js
     * setupFragment(): FragmentShader {
     *  return;
     * }
     * ```
     */
    setupFragment(): FragmentShader;
    /**
     * テクスチャとHTML要素の大きさのアスペクト比からuResolutionを設定します。
     * @param {DOMRect} rect 要素の矩形を渡します。省略された場合はthis.rectが使用されます。
     * @param {HTMLImageElement | HTMLVideoElement} mediaElement 画像、または動画。省略した場合はdata-tex-1に設定されたメディアが使用されます。
     * @returns {Vector4} uResolutionに設定するVector4オブジェクト
     * x: DOMの横幅
     * y: DOMの縦幅
     * z: 横幅に掛ける縦横比
     * w: 縦幅に掛ける縦横比
     */
    getResolution(rect?: DOMRect, mediaElement?: HTMLImageElement | HTMLVideoElement): Vector4;
    /**
     * 返却されたメッシュがthis.meshに設定されます。
     * @returns
     */
    setupMesh(): Object3D;
    /**
     * Layersを設定します。
     * @param layers
     */
    /**
     * Obの元になったHTML要素の画面から除外します。
     * 処理内容は以下の通りです。
     * ```js
     * disableOriginalElem(): void {
     *   this.$.el.draggable = false;
     *   this.$.el.style.opacity = "0";
     * }
     * ```
     */
    disableOriginalElem(): void;
    /**
     * 画面幅の変更に伴うエフェクトの位置や大きさの変更を行います。
     * 処理内容は以下の通りです。
     *
     * ```ts
     * async resize(duration: number = 1): Promise<void> {
     *   this.resizing = true;
     *
     *   const {
     *     $: { el },
     *     mesh,
     *     originalRect,
     *   } = this;
     *
     *   const nextRect = INode.getRect(el)!;
     *   const { x, y } = this.getWorldPosition(nextRect, viewport);
     *
     *   if (mesh === undefined) return;
     *
     *   const p1 = new Promise((onComplete) => {
     *     // utils.tween については{@link utils.tween こちら}を参照
     *     utils.tween(mesh.position, {
     *       x,
     *       y,
     *       duration,
     *       onComplete,
     *     })
     *   });
     *
     *   // 大きさの変更
     *   const p2 = new Promise((onComplete) => {
     *     utils.tween(this.scale, {
     *       width: nextRect.width / originalRect.width,
     *       height: nextRect.height / originalRect.height,
     *       depth: 1,
     *       duration,
     *       onUpdate: () => {
     *         mesh.scale.set(this.scale.width, this.scale.height, this.scale.depth);
     *       },
     *       onComplete
     *     })
     *   });
     *
     *   const p3 = new Promise((onComplete) => {
     *     if (!this.uniforms?.uResolution) return onComplete(null);
     *     const resolution = this.getResolution(nextRect);
     *     utils.tween(this.uniforms.uResolution.value, {
     *       x: resolution.x,
     *       y: resolution.y,
     *       z: resolution.z,
     *       w: resolution.w,
     *       duration,
     *       onComplete,
     *     })
     *   });
     *
     *   await Promise.all([p1, p2, p3]);
     *
     *   this.rect = nextRect;
     *
     *   this.resizing = false;
     * }
     * ```
     *
     * @param duration {@link config} の　`viewport.resizeDuration` の値が渡ってきます。
     * @returns
     */
    resize(duration?: number): Promise<void>;
    /**
     * HTMLの座標からワールド座標の位置を取得します。
     * @param duration
     * @returns
     */
    getWorldPosition(rect: DOMRect, viewport: Viewport): {
        x: number;
        y: number;
    };
    /**
     * スクロールに伴うメッシュの位置情報を変更します。
     * @param duration
     * @returns
     */
    scroll(): void;
    /**
     * フレーム毎に実行したい処理を記述します。
     */
    render(tick: number, delta: number): void;
    /**
     * Obオブジェクトの作成後に実行します。
     */
    afterInit(): void | Promise<void>;
    /**
     * 動画テクスチャを再生します。
     */
    playVideo(texId?: string): Promise<void>;
    /**
     * 動画テクスチャを停止します。
     */
    pauseVideo(texId?: string): void;
    /**
     * 戻り値で返却した`data-click-*`のアクションを実行します。例えば、getClickIdxで `1` を返却するように実装すると `data-click-1` の値に設定されたアクションが実行されます。実装を上書きしない場合は `1` が返ります。
     *
     * なお、`data-click-*`の使い方については [data-click](/reference/html/#data-click-) を参照してください。
     *
     * ```html copy
     * <!-- URL任意のURLに画面遷移。例）`1`を返却。`/detail.html`への画面遷移 -->
     * <!-- 別タブで画面を開く。例）`2`を返却。`/detail.html`を別タブで開く -->
     * <!-- `3`が返却された場合は`data-click-3`に設定されたObクラスのメソッド`goNext`を実行 -->
     * <div data-webgl="some-effect"
     *      data-interactive
     *      data-click-1="/detail.html"
     *      data-click-2="newTab,/detail.html"
     *      data-click-3="goNext"
     * ></div>
     * ```
     */
    getClickIdx(): number;
    /**
     * メッシュクリック時の挙動を制御します。
     *
     * Obクラスでは次のフローで click 時の挙動を制御しています。もし、メッシュクリック時の挙動を変更したい場合はこのメソッドをオーバーライドしてください。
     *
     * **Ob クラスの click イベントの制御**
     *
     * 1. {@link getClickIdx} の戻り値により `data-click-*` の値を取得します。
     * 2. `data-click-*` に設定されている値が
     *    - クラスに存在するメソッドだった場合
     *      -> そのメソッドを実行します。
     *
     *    - URL、もしくは newTab から始まる文字列だった場合
     *      -> ページ遷移を行います。
     */
    click({ meshUI, event, transition, }: {
        meshUI: MeshUI;
        event: Event;
        transition: Transition;
    }): void;
    link(args: string[], extra: {
        meshUI: MeshUI;
        event: Event;
        transition: Transition;
    }): void;
}
export {};
//# sourceMappingURL=Ob.d.ts.map