html5 画布笔触样式? [英] html5 canvas strokeStyle?

查看:21
本文介绍了html5 画布笔触样式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将图像映射到使用 strokeStyle 和画布模拟布料的3d"网格,我包含了该图像,但它目前充当背景图像,实际上并没有像涟漪一样随着布料"流动, IE 图像在网格流动时是静态的.这是不言自明的

代码很长,所以我不想全部粘贴在这里,但这里有一个备份,以防 jsfiddle 宕机:https://gist.github.com/simonsarris/5405304

这是最相关的部分:

//!!!新的超级棒的抽奖程序!太酷了,我们跳过将它命名为 draw2!Constraint.prototype.draw3 = 函数(otherP2){//现在亲爱的朋友们考虑一下我们所拥有的.每个盒子由两条线组成,//底部和最右边的.//从这些线我们可以推断出左上角和右下角的点//从这些点我们可以推导出矩形//从倾斜的矩形 vs 原始矩形,我们可以拉伸"//一个图像,使用 drawImage 的重载优点.//我们走了://目标矩形有 2 个点://左上角:Math.min(this.p2.x, otherP2.x), Math.min(this.p2.y, otherP2.y)//右下:(this.p1.x, this.p1.y)//图像目标矩形,由两点组成的矩形var dx = Math.min(this.p1.x, Math.min(this.p2.x, otherP2.x));var dy = Math.min(this.p1.y, Math.min(this.p2.y, otherP2.y));var dw = Math.abs(this.p1.x - Math.min(this.p2.x, otherP2.x));var dh = Math.abs(this.p1.y - Math.min(this.p2.y, otherP2.y));//调试:如果没有图像打开这个://ctx.strokeStyle = '石灰';//ctx.strokeRect(dx, dy, dw, dh);//源矩形2点://左上角:Math.min(this.p2.sx, otherP2.sx), Math.min(this.p2.sy, otherP2.sy)//右下:(this.p1.sx, this.p1.sy)//这些不需要每次都计算,//对于给定的约束,它们永远不会改变//仅第一次计算它们.我可以早点做,但我很懒//和它过去的午夜.另见:http://www.youtube.com/watch?v=FwaQxDkpcHY#t=64s如果(this.sx === 未定义){this.sx = Math.min(this.p1.sx, Math.min(this.p2.sx, otherP2.sx));this.sy = Math.min(this.p1.sy, Math.min(this.p2.sy, otherP2.sy));this.sw = Math.abs(this.p1.sx - Math.min(this.p2.sx, otherP2.sx));this.sh = Math.abs(this.p1.sy - Math.min(this.p2.sy, otherP2.sy));}var sx = this.sx;var sy = this.sy;var sw = this.sw;var sh = this.sh;//调试:如果没有图像打开这个://ctx.strokeStyle = '红色';//ctx.strokeRect(sx, sy, sw, sh);//如果我们有源矩形和目标矩形,那么我们就可以映射图像//使用 drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)//唯一的问题,我们并没有完全处理矩形......//但我们会处理的.无论如何,转换都有kooties.ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);};

I am trying to map an image to a "3d" grid that simulates cloth using strokeStyle and canvas, i have the image included but it is currently acting as a background image and not actually flowing with the "cloth" as is ripples, I.E the image is static as the grid flows. here's the jsfiddle which is self explanatory ( only works in Chrome). any help is much appreciated. here is the javascript that renders the image into the background, How do i stop from rendering as a background image and only make it fill the grid?:

function update() {

    var img = new Image();
    img.src = 'http://free-textures.got3d.com/architectural/free-stone-wall-   textures/images/free-stone-wall-texture-002.jpg';
    img.onload = function() {

        // create pattern
        var ptrn = ctx.createPattern(img, 'repeat');

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

        physics.update();

        ctx.strokeStyle = ptrn;
        ctx.beginPath();
        var i = points.length;
        while (i--) points[i].draw();
        ctx.stroke();

        requestAnimFrame(update);
    }
}

Hers's the original codepen I'm working from. `updated fiddle with image outside function update(): It currently seems to actually fill the cells as well as applying it as a background image. is there any way to stop it becoming a background image and only apply it to fill the grid? I've tried this:
ctx.fillStyle = ptrn; and removing line 260:
ctx.strokeStyle = ptrn; but it seems to remove the background image just displaying it as a black grid... thank you again for the patience

解决方案

Oh my! Great question!

So let's see what we've got. A system that has a bunch of "constraints", which are sets of 2 points. Contraints themselves come in pairs, and they make two lines, forming a shape (the bottom-right of a box).

If we were to draw every constraint line individually we'd see this:

That's all horizontal red lines and vertical blue lines. Drawing a single one we'd just see that shape, and each long red line is really hundreds of little lines, the bottom of each shape, end to end. There are several hundred s here, and together they make it look like a cohesive mesh. The fact that each one is already individual makes this easy for us.

That shape is all we need to determine a sort-of bounding box. And it looks like each Point in a Constraint comes with original values, so we'll save those as sx and sy.

If we know the bounds of the boxes at their new location, and we know the original bounds beecause we've saved all the Point's values for the Contraints, then we should be golden.

Once we have the original bounding box of a Constraint and its current bounding box, why, all we have to do is call drawImage with both boxes: ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);

I wrote a new Constraint.prototype.draw routine, It looks like this:

And so on.

There are a few ways you could "patch" the holes, and its really up to you, otherwise you'll have to finagle with transformations.

Have a look at the code. I didn't change much. Look for !!! in the code (my edits) and DEBUG: in the code (debug code in case the image does not load or you wanna see the wireframes).

http://jsfiddle.net/simonsarris/Kuw6P/

The code is long so I don't wanna paste it all here, but here's a backup in case jsfiddle goes down: https://gist.github.com/simonsarris/5405304

And here's the most relevant part:

// !!! new super awesome draw routine! So cool we skipped naming it draw2!
Constraint.prototype.draw3 = function(otherP2) {

  // NOW dear friends consider what we have. Each box is made out of two lines,
  // the bottom and rightmost ones.
  // From these lines we can deduce the topleft and bottom-right points
  // From these points we can deduce rectangles
  // From the skewed rectangle vs the original rectangle we can "stretch"
  // an image, using drawImage's overloaded goodness.

  // AND WE'RE OFF:

  // destination rect has 2 points:
  //top left: Math.min(this.p2.x, otherP2.x), Math.min(this.p2.y, otherP2.y)
  //bottom right: (this.p1.x, this.p1.y)

  // image destination rectangle, a rect made from the two points
  var dx = Math.min(this.p1.x,  Math.min(this.p2.x, otherP2.x));
  var dy = Math.min(this.p1.y,  Math.min(this.p2.y, otherP2.y));
  var dw = Math.abs(this.p1.x - Math.min(this.p2.x, otherP2.x));
  var dh = Math.abs(this.p1.y - Math.min(this.p2.y, otherP2.y));
  // DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
  //ctx.strokeStyle = 'lime';
  //ctx.strokeRect(dx, dy, dw, dh);

  // source rect 2 points:
  //top left: Math.min(this.p2.sx, otherP2.sx), Math.min(this.p2.sy, otherP2.sy)
  //bottom right: (this.p1.sx, this.p1.sy)

  // these do NOT need to be caluclated every time,
  // they never change for a given constraint
  // calculate them the first time only. I could do this earlier but I'm lazy
  // and its past midnight. See also: http://www.youtube.com/watch?v=FwaQxDkpcHY#t=64s
  if (this.sx === undefined) {
    this.sx = Math.min(this.p1.sx,  Math.min(this.p2.sx, otherP2.sx));
    this.sy = Math.min(this.p1.sy,  Math.min(this.p2.sy, otherP2.sy));
    this.sw = Math.abs(this.p1.sx - Math.min(this.p2.sx, otherP2.sx));
    this.sh = Math.abs(this.p1.sy - Math.min(this.p2.sy, otherP2.sy));
  }
  var sx = this.sx;
  var sy = this.sy;
  var sw = this.sw;
  var sh = this.sh;
  // DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
  //ctx.strokeStyle = 'red';
  //ctx.strokeRect(sx, sy, sw, sh);


  // IF we have a source and destination rectangle, then we can map an image
  // piece using drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
  // Only problem, we're not exactly dealing with rectangles....
  // But we'll deal. Transformations have kooties anyways.
  ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
};

这篇关于html5 画布笔触样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆