• <tfoot id='FIz73'></tfoot>
    <legend id='FIz73'><style id='FIz73'><dir id='FIz73'><q id='FIz73'></q></dir></style></legend>

        <bdo id='FIz73'></bdo><ul id='FIz73'></ul>

        <small id='FIz73'></small><noframes id='FIz73'>

        <i id='FIz73'><tr id='FIz73'><dt id='FIz73'><q id='FIz73'><span id='FIz73'><b id='FIz73'><form id='FIz73'><ins id='FIz73'></ins><ul id='FIz73'></ul><sub id='FIz73'></sub></form><legend id='FIz73'></legend><bdo id='FIz73'><pre id='FIz73'><center id='FIz73'></center></pre></bdo></b><th id='FIz73'></th></span></q></dt></tr></i><div id='FIz73'><tfoot id='FIz73'></tfoot><dl id='FIz73'><fieldset id='FIz73'></fieldset></dl></div>

      1. 仅转换 Path2D 的样式

        Transform only the styling of a Path2D(仅转换 Path2D 的样式)
          <tbody id='zg1ox'></tbody>
        • <bdo id='zg1ox'></bdo><ul id='zg1ox'></ul>

          <small id='zg1ox'></small><noframes id='zg1ox'>

            <legend id='zg1ox'><style id='zg1ox'><dir id='zg1ox'><q id='zg1ox'></q></dir></style></legend>
            • <tfoot id='zg1ox'></tfoot>

                <i id='zg1ox'><tr id='zg1ox'><dt id='zg1ox'><q id='zg1ox'><span id='zg1ox'><b id='zg1ox'><form id='zg1ox'><ins id='zg1ox'></ins><ul id='zg1ox'></ul><sub id='zg1ox'></sub></form><legend id='zg1ox'></legend><bdo id='zg1ox'><pre id='zg1ox'><center id='zg1ox'></center></pre></bdo></b><th id='zg1ox'></th></span></q></dt></tr></i><div id='zg1ox'><tfoot id='zg1ox'></tfoot><dl id='zg1ox'><fieldset id='zg1ox'></fieldset></dl></div>
                • 本文介绍了仅转换 Path2D 的样式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  在 canvas 2D API 中,我们可以首先使用一个上下文的转换定义一个子路径,然后只为 fill()stroke() 调用更改该上下文的转换,这会对 stylings 产生影响,例如 fillStylelineWidth 和其他可见属性,但会保留已定义的子路径.当我们想要在保持相同笔划宽度的同时放大矢量形状时,这非常方便.

                  In the canvas 2D API, we can first define a subpath using one context's transformation and then change that context's transformation for only the fill() or stroke() calls, which would have effect on the stylings, like fillStyle, lineWidth and other visible properties, but which will leave the sub-path as defined. This is quite convenient when we want to zoom in vector-shapes while keeping the same stroke-width.

                  这是一个简单的例子,其中只有 lineWidth 受变量 zoom 变换的影响:

                  Here is a simple example where only the lineWidth is affected by the variable zoom transformation:

                  const canvas = document.getElementById('canvas');
                  const ctx = canvas.getContext('2d');
                  
                  let zoom = 1;
                  let speed = 0.1;
                  requestAnimationFrame(update);
                  
                  function update() {
                    if( zoom >= 10 || zoom <= 0.1 ) speed *= -1;
                    zoom += speed;
                    draw();
                    requestAnimationFrame(update);
                  }
                  
                  function draw() {
                    ctx.setTransform(1, 0, 0, 1, 0, 0);
                    ctx.clearRect(0,0,canvas.width,canvas.height);
                    // define the subpath at identity matrix
                    ctx.beginPath();
                    ctx.moveTo(10 ,80);
                    ctx.quadraticCurveTo(52.5,10,95,80);
                    ctx.quadraticCurveTo(137.5,150,180,80);
                    // stroke zoomed
                    ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
                    ctx.stroke();
                  }

                  <canvas id="canvas"></canvas>

                  使用 Path2D API,我们必须通过此子路径直接在 ctx.fill(path)ctx.stroke(path) 方法中.
                  这意味着我们不能像以前那样将样式与子路径声明分开:

                  With the Path2D API, we have to pass this subpath directly in either ctx.fill(path) or ctx.stroke(path) methods.
                  This means we can't separate the stylings from the subpath declaration like we did before:

                  const canvas = document.getElementById('canvas');
                  const ctx = canvas.getContext('2d');
                  
                  let zoom = 1;
                  let speed = 0.1;
                  requestAnimationFrame(update);
                  
                  function update() {
                    if( zoom >= 10 || zoom <= 0.1 ) speed *= -1;
                    zoom += speed;
                    draw();
                    requestAnimationFrame(update);
                  }
                  
                  function draw() {
                    ctx.setTransform(1, 0, 0, 1, 0, 0);
                    ctx.clearRect(0,0,canvas.width,canvas.height);
                    // define the subpath at identity matrix
                    // (declared in 'draw' just for the example, would be the same anyway outside)
                    const path = new Path2D("M 10 80 Q 52.5 10, 95 80 T 180 80");
                    // stroke zoomed
                    ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
                    ctx.stroke(path);
                  }

                  <canvas id="canvas"></canvas>

                  在使用这个原本方便的 Path2D API 时有没有办法做到这一点?

                  Is there no way of doing this while using this otherwise convenient Path2D API?

                  推荐答案

                  有一种方法可以通过传递 DOMMatrix1Path2D.prototype.addPath 方法.

                  There is a way to transform a Path2D object by passing a DOMMatrix1 to the Path2D.prototype.addPath method.

                  所以我们实际上可以通过传递我们的 Path2d 的转换副本来实现相同的结果:

                  So we can actually achieve the same result by passing a transformed copy of our Path2d:

                  const transformPath = (path, matrix) => {
                    const copy = new Path2D();
                    copy.addPath(path, matrix);
                    return copy;
                  };
                  // ...
                  ctx.stroke( transformPath( path, {a: 1/zoom, d: 1/zoom } );
                  

                  但是,您会注意到我们必须使我们的 path-matrix 相对于 样式 之一.
                  新的 DOMMatrix API 大大简化了矩阵转换2,但它使这种方法肯定比 beginPath() 方式更复杂,很不幸我们无法对Path2D 对象本身,甚至只是在构造函数上也有这个 transform 参数,但这是我知道的唯一方法......

                  However, you'll notice that we have to make our path-matrix relatively from the styling one.
                  The new DOMMatrix API eases matrix transforms a lot2, but it makes this approach definitely more convoluted than the beginPath() way, that's quite unfortunate we can't act on the Path2D object itself or even just have this transform parameter on the constructor too, but that's the only way I know of...

                  const transformPath = (path, matrix) => {
                    const copy = new Path2D();
                    copy.addPath(path, matrix);
                    return copy;
                  };
                  
                  const canvas = document.getElementById('canvas');
                  const ctx = canvas.getContext('2d');
                  // define the subpath
                  const path = new Path2D("M 10 80 Q 52.5 10, 95 80 T 180 80");
                  
                  let zoom = 1;
                  let speed = 0.1;
                  requestAnimationFrame(update);
                  
                  function update() {
                    if( zoom >= 10 || zoom <= 0.1 ) speed *= -1;
                    zoom += speed;
                    draw();
                    requestAnimationFrame(update);
                  }
                  
                  function draw() {
                    ctx.setTransform(1, 0, 0, 1, 0, 0);
                    ctx.clearRect(0,0,canvas.width,canvas.height);  
                    // zoom the stylings
                    ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
                    // create our transformed path
                    const invertMatrix = {a: 1/zoom, d: 1/zoom};
                    ctx.stroke(transformPath(path, invertMatrix));
                  }

                  <canvas id="canvas"></canvas>

                  1.实际上它不需要是一个实际的 DOMMatrix,任何具有其属性的对象都可以
                  2.我们现在甚至可以在 ctx.setTransform(matrix) 中使用这些对象.

                  1. Actually it doesn't need to be an actual DOMMatrix, any object with its properties will do
                  2. We can now even use such objects in ctx.setTransform(matrix).

                  这篇关于仅转换 Path2D 的样式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  quot;Status Code:200 OK (from ServiceWorker)quot; in Chrome Network DevTools?(“状态码:200 OK(来自 ServiceWorker)在 Chrome 网络开发工具中?)
                  How to set a header for a HTTP GET request, and trigger file download?(如何为 HTTP GET 请求设置标头并触发文件下载?)
                  Adding custom HTTP headers using JavaScript(使用 JavaScript 添加自定义 HTTP 标头)
                  SQL Query DocumentDB in Azure Functions by an integer not working(通过整数在 Azure Functions 中 SQL 查询 DocumentDB 不起作用)
                  Azure Functions [JavaScript / Node.js] - HTTP call, good practices(Azure Functions [JavaScript/Node.js] - HTTP 调用,良好实践)
                  Azure Functions - Import Custom Node Module(Azure Functions - 导入自定义节点模块)
                    <tbody id='deOwA'></tbody>

                      • <i id='deOwA'><tr id='deOwA'><dt id='deOwA'><q id='deOwA'><span id='deOwA'><b id='deOwA'><form id='deOwA'><ins id='deOwA'></ins><ul id='deOwA'></ul><sub id='deOwA'></sub></form><legend id='deOwA'></legend><bdo id='deOwA'><pre id='deOwA'><center id='deOwA'></center></pre></bdo></b><th id='deOwA'></th></span></q></dt></tr></i><div id='deOwA'><tfoot id='deOwA'></tfoot><dl id='deOwA'><fieldset id='deOwA'></fieldset></dl></div>
                      • <small id='deOwA'></small><noframes id='deOwA'>

                          <legend id='deOwA'><style id='deOwA'><dir id='deOwA'><q id='deOwA'></q></dir></style></legend>
                            <bdo id='deOwA'></bdo><ul id='deOwA'></ul>
                          • <tfoot id='deOwA'></tfoot>