canvas 旋轉/翻轉

 <!DOCTYPE html>

<html>

<head>

<title>Rotated and Flipped Tilde on Canvas</title>

<style>

  body { margin: 20px; }

  canvas { border: 1px solid black; }

  .controls { margin-bottom: 10px; }

  .controls label { margin-right: 10px; }

</style>

</head>

<body>


<div class="controls">

  <label><input type="checkbox" id="rotateCheck" checked> 旋轉90度</label>

  <label><input type="checkbox" id="flipHorizontalCheck"> 水平翻轉</label>

  <label><input type="checkbox" id="flipVerticalCheck"> 垂直翻轉</label>

</div>


<canvas id="myCanvas" width="500" height="300"></canvas>


<script>

  const canvas = document.getElementById('myCanvas');

  const ctx = canvas.getContext('2d');


  const rotateCheck = document.getElementById('rotateCheck');

  const flipHorizontalCheck = document.getElementById('flipHorizontalCheck');

  const flipVerticalCheck = document.getElementById('flipVerticalCheck');


  const fontSize = 50;

  const textToDraw = '~A'; // 使用 '~A' 來看清翻轉效果


  function draw() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    ctx.font = `${fontSize}px Arial`;

    ctx.fillStyle = 'blue';

    ctx.textAlign = 'center';

    ctx.textBaseline = 'middle';


    const x = 100;

    const y = 150;


    // --- 繪製原始參考(未變換) ---

    ctx.fillStyle = 'lightgray';

    ctx.fillText(`原始: ${textToDraw}`, x + 150, y - 50);

    ctx.fillStyle = 'blue';



    // --- 繪製變換後的文字 ---

    ctx.save(); // 儲存初始狀態


    // 1. 移動原點到目標位置

    ctx.translate(x, y);


    // 2. 旋轉 (如果勾選)

    if (rotateCheck.checked) {

      ctx.rotate(Math.PI / 2); // 旋轉90度

    }


    // 3. 翻轉 (如果勾選)

    let scaleX = 1;

    let scaleY = 1;

    if (flipHorizontalCheck.checked) {

      scaleX = -1;

    }

    if (flipVerticalCheck.checked) {

      scaleY = -1;

    }

    ctx.scale(scaleX, scaleY);


    // 4. 在新的 (0,0) 位置繪製文字

    // (textAlign和textBaseline設為center/middle有助於此)

    ctx.fillText(textToDraw, 0, 0);


    ctx.restore(); // 恢復到儲存的繪圖狀態



    // --- 輔助線:標示原點和軸向 (變換後) ---

    ctx.save();

    ctx.translate(x, y); // 移動到與文字相同的原點

    // 旋轉軸 (如果文字也旋轉了)

    if (rotateCheck.checked) {

        ctx.rotate(Math.PI / 2);

    }

    // 繪製 X 軸 (變換後)

    ctx.beginPath();

    ctx.moveTo(-fontSize, 0);

    ctx.lineTo(fontSize, 0);

    ctx.strokeStyle = 'red';

    ctx.lineWidth = 1;

    ctx.stroke();

    ctx.fillText('X', fontSize + 10, 0);


    // 繪製 Y 軸 (變換後)

    ctx.beginPath();

    ctx.moveTo(0, -fontSize);

    ctx.lineTo(0, fontSize);

    ctx.strokeStyle = 'green';

    ctx.lineWidth = 1;

    ctx.stroke();

    ctx.fillText('Y', 0, fontSize + 10);

    ctx.restore();

  }


  // 監聽 checkbox 變化

  rotateCheck.addEventListener('change', draw);

  flipHorizontalCheck.addEventListener('change', draw);

  flipVerticalCheck.addEventListener('change', draw);


  // 初始繪製

  draw();

</script>


</body>

</html>

留言

這個網誌中的熱門文章

Offscreen Canvas

外部網頁新增 Google 日曆行程(URL模板)

計算 Canvas 文字最大字體