MENU

JavaScriptCanvas画像処理

【JavaScript】 Canvasのtranslateやscaleなどをリセットする方法

更新日:2021/09/01

 

JavaScriptのCanvasAPIにはtranslateやscaleなどの変換メソッドがあります。

 

しかし変換をリセットするメソッドが存在しません。

 

そこで、変換内容をリセットする方法をお伝えします。

 

リセットするコード

 

translateやscale、rotateなどの変換関数を全てリセットするなら、次のコードを実行すればよい。

 


context.setTransform(1,0,0,1,0,0);

 

解説

 

translateなどの関数を実行すると、変換マトリックスが順番に登録されます。

 

その際、各関数はtransformに置き換えることができます。

 

例:
translate( x , y ) → transform( 1, 0, 0, 1, x, y )
scale(x, y) → transform( x, 0, 0, y, 0, 0 )

 

setTransformは登録されたマトリクスをリセットしてくれます。
そして、新たなマトリクスを登録します。

 

しかしリセットのみで終わってくれるのならよかったのですが…
何らかの引数を指定する必要があるのは、少し面倒です。

 

そこで、変換前と変換後が同じになる値を引数として与えます。

 

その例が、次のコードです。

 

context.setTransform( 1,0,0,1,0,0 );

特定の変換のみリセットしたい

 

変換を全てリセットするのではなくてscaleなど特定の変換のみをリセットしたい場合は、変換内容を記憶しておき、リセット後に必要な変換を再度適用します。

 

次のコンストラクターは、変換関数の登録と実行、およびリセットをおこないます。

 


const TransControl = function ( context ){
    const transFUnc = {
        "scale" : CanvasRenderingContext2D.prototype.scale,
        "translate" : CanvasRenderingContext2D.prototype.translate,
        "rotate" : CanvasRenderingContext2D.prototype.rotate,
    };
    let commandData = [];

    const setAndRunCommand = ( name , arg ) => {
        runCommand( name , arg );
        commandData.push( [ name , arg ] );
    }
    const runCommand = ( name , arg ) => transFUnc[name].apply( context , arg );
    const resetCommand = name =>{
        commandData = commandData.filter( data => data[0] !== name );
        context.setTransform( 1,0,0,1,0,0 );
        commandData.forEach( data => runCommand( data[0] , data[1] ) );
    }

    Object.keys( transFUnc ).forEach( name =>{
        this[name] = (...arg)=>setAndRunCommand( name , arg );
        this[ "reset" + name.replace( /^[a-z]/g,t => t.toUpperCase() ) ]
            = ()=>resetCommand( name );
    })

}

 

コンストラクターからインスタンスを作成すると、次のメソッドが使用可能になります。

 

■変換登録&実行メソッド

 

同名の変換メソッドと同じ引数を受け付けます。

 

scaleメソッド
translateメソッド
rotateメソッド

 

■リセット

 

登録したマトリックスをリセットします。
引数はありません。

 

resetScaleメソッド
resetTranslateメソッド
resetRotateメソッド

 

使用例

 


window.addEventListener( "DOMContentLoaded" , ()=> {
    const context = document.getElementById( "cv" ).getContext("2d");

    const tc = new TransControl( context );

    tc.scale( 0.5 , 1 );
    tc.translate( 100 , 100 );
    tc.translate( 100 , 0 );

    tc.resetScale(); // scaleのみリセット

    context.fillRect( 10 , 10 , 100 , 100 )

});

 

なおリセットによる影響を受けるのは、リセット以降に描画される図形のみです。

 

既存の図形も変更したいときは、変換メソッドと同様に描画メソッドも記憶しておく必要があります。

けーちゃんおススメJavaScript入門書

  • スラスラ読める JavaScript ふりがなプログラミング
  • プログラム未経験者がJavaScript始めるならコレ!
    コードを掲載して自分で理解しろという投げっぱなしな入門書とは異なり、コードに一つ一つどんなことをやっているかをふりがなという形式で解説しています。
    それでいてJavaScriptの基礎と応用を学べる良書です。
  • これからWebをはじめる人のHTML&CSS、JavaScriptのきほんのきほん
  • JavaScriptの機能を実践で活かすにはHTMLやCSSの知識が不可欠です。
    しかしそれらの知識があることが前提として書かれている書籍が多い中、この本は総合的な知識を身に着けることができます。
    HTMLやCSSの知識も不安な方には、ぴったりの一冊です
  •  

    入門書の役割は、自分のやりたいことをネットで調べることができるようになるための、基礎的な知識の獲得です。
    まずはこれらの本でしっかりと基礎知識を身につけましょう。
    そしてもっと高度なことや専門的なことはネットで調べ、情報が足りないと感じたら書籍を購入してください。


    記事の内容について

     

    こんにちはけーちゃんです。
    説明するのって難しいですね。


    「なんか言ってることおかしくない?」
    たぶん、こんなご意見あると思います。

    裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。

    そんなときは、ご意見もらえたら嬉しいです。

    ご意見はこちら。
    https://note.affi-sapo-sv.com/info.php

    【お願い】

    お願い

    ■このページのURL


    ■このページのタイトル


    ■リンクタグ


    ※リンクして頂いた方でご希望者には貴サイトの紹介記事を作成してリンクを設置します。
    サイト上部の問い合わせよりご連絡ください。
    ただしサイトのジャンルによっては、お断りさせていただくことがあります。