【问题标题】:Odd behavior of clip?剪辑的奇怪行为?
【发布时间】:2016-01-12 14:46:40
【问题描述】:

以下创建了一个意外的剪辑路径。是不是因为 从一个弧的末端移动到下一个弧的开始?圆圈原来是椭圆,这也是出乎意料的。

var canvas3=document.getElementById("drawing3"); 
var ct=canvas3.getContext("2d"); 

ct.beginPath();
ct.arc(50,80,30,0,Math.PI*2,false);
ct.arc(120,40,60,0,Math.PI*2,true);
ct.arc(180,40,30,0,Math.PI*2,true);
ct.arc(240,40,30,0,Math.PI*2,true);
ct.clip();

ct.fillStyle="yellow";
ct.fillRect(10,10,400,200);
ct.fillStyle="magenta";
ct.font = "40px sans-serif";
ct.fillText("what's this?",30,70);

顺便问一下,剪辑区域总是必须以 beginPath() 开头吗?

【问题讨论】:

    标签: javascript html canvas clip


    【解决方案1】:

    为什么用椭圆而不是圆弧

    虽然您没有包含 CSS,但当使用 CSS 调整画布元素的大小时,画布绘图会变形。 html5 画布的默认大小为 300x150,因此使用 CSS 调整其大小会拉伸或挤压后续绘图,除非 CSS 将画布大小调整为与其原始 2:1 比例完全成比例。

    因此,如果您想调整画布大小,请直接更改元素的大小:

    var canvas3=document.getElementById("drawing3"); 
    canvas3.width=400;
    canvas3.height=300;
    

    为什么beginPath 有用(必不可少!)

    context.clip 始终作用于最后一组路径命令,一组路径命令应该context.beginPath 开头。所以是的,剪辑应该总是以 context.beginPath 开头。

    为什么beginPath 有用(总是使用它!): 如果您发出多组路径命令而不用 beginPath 开始每组,那么每个新组也将执行所有以前的组。您的路径将只是一张长图,而不是不同的图。

    修复相互关联的圈子

    context.arc 是画布路径绘制命令。

    路径命令将始终连接(用一条线)出现在context.beginPathcontext.stroke or context.fill 之间的所有绘图。

    但是您可以使用context.moveTo 命令“拿起铅笔并将其移动到下一个圆心”的路径。这将防止您的圈子相互连接。

    // pick up the pencil and move it to the next arc's centerpoint
    ct.moveTo(x,y);
    // and draw the arc around the centerpoint
    ct.arc(x,y,r,0,Math.PI*2,false);
    

    以下是重构为在弧之间“拿起铅笔”的代码:

    var canvas3=document.getElementById("drawing3"); 
    var ct=canvas3.getContext("2d"); 
    
    ct.beginPath();
    arcAtXY(50,80,30);
    arcAtXY(120,40,60);
    arcAtXY(180,40,30);
    arcAtXY(240,40,30);
    ct.clip();
    
    ct.fillStyle="yellow";
    ct.fillRect(10,10,400,200);
    ct.fillStyle="magenta";
    ct.font = "40px sans-serif";
    ct.fillText("what's this?",30,70);
    
    function arcAtXY(x,y,r){
        ct.moveTo(x,y);
        ct.arc(x,y,r,0,Math.PI*2,false);
    }
    canvas{border:1px solid red;}
    <canvas id="drawing3" width=300 height=300></canvas>

    与您的设计没有直接关系的额外想法

    如果您想描边圆而不是填充它们,您将移动到下一个圆的周长而不是它的中心点。移动到中心点会导致从中心点到周边绘制一条自动线。

    function arcAtXY(x,y,r){
        ct.moveTo(x+r,y);
        ct.arc(x,y,r,0,Math.PI*2,false);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-08
      • 2018-02-21
      • 2014-11-03
      • 2023-04-03
      相关资源
      最近更新 更多