最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Changing Pattern Size in Html5 Canvas - Stack Overflow

programmeradmin0浏览0评论

My Problem: I've got an ImageObject, that is being used to create a PatternObject. My problem is, that i changed the width and height properties of the Image before creating the pattern, but that doesn't actually remap the image (and that is also no problem). The thing is, that I now have got a pattern, that is of a different size (the original image size) than the image itself. If I want to draw a line with the fillStyle of that pattern, it doesn't fit (because I need a pattern of the new size).

My question: Is there an easy way, to achieve that the pattern's width and height can be adjusted?

My tries and why I dont like them:

1) Render the original image to a canvas with the new size and create the pattern from that. Didn't use this, because the pattern cannot be loaded directly as a result of the canvas being created and rendered to too slowly. But I want that pattern directly

2) Calculate the variance between the new image size and the original one, change the lineWidth of the context, so the patterns height fits exactly and scale the line down, so it has a nice size. Didn't use that because I render in realtime and this is way too slow to be used later in webapps.

My Problem: I've got an ImageObject, that is being used to create a PatternObject. My problem is, that i changed the width and height properties of the Image before creating the pattern, but that doesn't actually remap the image (and that is also no problem). The thing is, that I now have got a pattern, that is of a different size (the original image size) than the image itself. If I want to draw a line with the fillStyle of that pattern, it doesn't fit (because I need a pattern of the new size).

My question: Is there an easy way, to achieve that the pattern's width and height can be adjusted?

My tries and why I dont like them:

1) Render the original image to a canvas with the new size and create the pattern from that. Didn't use this, because the pattern cannot be loaded directly as a result of the canvas being created and rendered to too slowly. But I want that pattern directly

2) Calculate the variance between the new image size and the original one, change the lineWidth of the context, so the patterns height fits exactly and scale the line down, so it has a nice size. Didn't use that because I render in realtime and this is way too slow to be used later in webapps.

Share Improve this question edited Oct 19, 2018 at 18:47 Davis Broda 4,1375 gold badges25 silver badges38 bronze badges asked Jun 21, 2013 at 23:58 ChaosChaos 3822 silver badges11 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 9

Using canvas (your step 1) is the most flexible way.

It's not slower using a canvas to draw on another canvas than using an image directly. They both use the same element basis (you're blitting a bitmap just as you do with an image).

(Update: Drawing using pattern as style do go through an extra step of a local transformation matrix for the pattern in more recent browsers.)

Create a new canvas in the size of the pattern and simple draw the image into it:

patternCtx.drawImage(img, 0, 0, patternWidth, patternHeight);

Then use the canvas of patternCtx as basis for the pattern (internally the pattern caches this image the first time it's drawn, from there, if possible, it just doubles out what it has until the whole canvas is filled).

The other option is to pre-scale the images to all the sizes you need them to be, load them all in, and then choose the image which size is the one you need.

The third is to draw the image yourself as a pattern. This however is not so efficient pared to the built-in method, though using the above mentioned method (internal) you can get a usable result.

Example of manual patterning:

var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
  fillPattern(this, 64, 64);
  change.onchange = change.oninput = function() {
    fillPattern(img, this.value, this.value);
  }
};
img.src = "//i.sstatic/tkBVh.png";

// Fills canvas with image as pattern at size w,h
function fillPattern(img, w, h) {

    //draw once
    ctx.drawImage(img, 0, 0, w, h);

    while (w < canvas.width) {
        ctx.drawImage(canvas, w, 0);
        w <<= 1;  // shift left 1 = *2 but slightly faster
    }
    while (h < canvas.height) {
        ctx.drawImage(canvas, 0, h);
        h <<= 1;
    }
}
<input id=change type=range min=8 max=120 value=64><br>
<canvas id=canvas width=500 height=400></canvas>

(or with a video as pattern).

发布评论

评论列表(0)

  1. 暂无评论