问题描述
猜猜帖子的标题可能需要编辑,但现在我不知道问题在哪里。我在这里和其他地方读过页面和类似问题的答案。一个Stack Overflow的答案是特别接近,但我不明白。
Guess the title of the post may need editing, but for now I don't know where the problems are. I have read pages and answers to similar questions, here and elsewhere. One Stack Overflow answer is especially close, but I don't understand it.
我想要一个函数,在画布上绘制多边形在所需的坐标,并填充一些从文件加载的背景图像(足够大,不需要平铺)。三角形对于测试是很好的。显然我应该使用drawImage和clip,并给多边形一个边框,我可以重用相同的路径为剪辑和笔触。显然我应该保持顺序
I want a function, to draw polygons on canvas at desired coordinates and to fill them with some background image loaded from a file (large enough that no tiling is needed). Triangles would be fine for a test. Apparently I should use drawImage and clip, and to give the polygon a border, I can resuse the same path for the clip and the stroke. Also apparently I should keep the order of
- define path
- save
- clip
- drawImage
- restore
- stroke.
也可以读取图像一次。 (如果你想让我引用所有这些假设的来源,我会寻找我在哪里看到他们。大多数在Stack Overflow)
Also read somewhere that it is enough to load the image once. (If uou want me to quote sources for all these assumptions, I will look for where I saw them. Most of them on Stack Overflow)
HTML是一个空的
<body onload = "main ();"></body>
第一种方法,假装浏览器会等待图片加载:
First approach, pretending that the browser will wait for the picture to load:
var ctx, img;
var image_path = 'bg.jpg';
function main () {
var CANVAS_SIZE = 600;
var view_field_cnv = document.createElement ('canvas');
view_field_cnv.width = CANVAS_SIZE;
view_field_cnv.height = CANVAS_SIZE;
view_field_cnv.style.border = "1px solid";
document.body.appendChild (view_field_cnv);
ctx = view_field_cnv.getContext ('2d');
img = document.createElement ('img');
img.src = image_path;
place_triangle (0, 0);
place_triangle (300, 300);
place_triangle (500, 500);
place_triangle (0, 0);
}
function place_triangle (x, y) {
console.log (x, y);
ctx.beginPath ();
ctx.moveTo (x + 10, y);
ctx.lineTo (x + 110, y);
ctx.lineTo (x + 60, y + 40);
ctx.closePath ();
img = document.createElement ('img');
img.src = image_path;
ctx.save ();
ctx.clip ();
ctx.drawImage (img, x, y);
ctx.restore ();
ctx.stroke ();
}
绘制所有三个三角形,
That draws all three triangles but no clipped images.
第二次尝试,使用drawImage在image.onload内:
Second try, with drawImage inside image.onload:
var ctx;
var image_path = 'bg.jpg';
function main () {
var CANVAS_SIZE = 600;
var view_field_cnv = document.createElement ('canvas');
view_field_cnv.width = CANVAS_SIZE;
view_field_cnv.height = CANVAS_SIZE;
view_field_cnv.style.border = "1px solid";
document.body.appendChild (view_field_cnv);
ctx = view_field_cnv.getContext ('2d');
place_triangle (0, 0);
place_triangle (300, 300);
place_triangle (500, 500);
place_triangle (0, 0);
}
function place_triangle (x, y) {
console.log (x, y);
var img;
ctx.beginPath ();
ctx.moveTo (x + 10, y);
ctx.lineTo (x + 110, y);
ctx.lineTo (x + 60, y + 40);
ctx.closePath ();
img = document.createElement ('img');
img.src = image_path;
img.onload = function () {
ctx.save ();
ctx.clip ();
ctx.drawImage (img, x, y);
ctx.restore ();
ctx.stroke ();
}
}
,但只有一个三角形,最后一个。只是注释掉保存和恢复没有帮助。
This one does draw the clipped image, but only one triangle, the last one. Just commenting out save and restore doesn't help.
所以,我不明白加载图像,保存,还原和大概一百万其他的东西。
So, I don't understand loading images, saving, restoring and probably a million other things. Where be the bugs?
推荐答案
我看到你已经了解了剪辑的基本知识:
I see you already understand the basics of clipping:
-
保存上下文,定义路径,剪辑,drawImage,恢复上下文。
save context, define path, clip, drawImage, restore context.
如果您不想让笔触与剪辑的图像重叠,您可以在剪辑前敲击。
you can stroke before clipping if you don't want the stroke to overlap the clipped image.
这里是示例代码和演示:
Here's example code and a Demo: http://jsfiddle.net/m1erickson/p0fup425/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// image loader
// put the paths to your images in imageURLs[]
var imageURLs=[];
// push all your image urls!
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/norwayFlag.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/multple/swedishFlag.jpg");
// the loaded images will be placed in images[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
// clip image#1
clippingPath([10,70,50,10,90,70],imgs[0],10,10);
// clip image#2
clippingPath([10,170,50,110,90,170],imgs[1],10,110);
// append the original images for demo purposes
document.body.appendChild(imgs[0]);
document.body.appendChild(imgs[1]);
}
function clippingPath(pathPoints,img,x,y){
// save the unclipped context
ctx.save();
// define the path that will be clipped to
ctx.beginPath();
ctx.moveTo(pathPoints[0],pathPoints[1]);
// this demo has a known number of polygon points
// but include a loop of "lineTo's" if you have a variable number of points
ctx.lineTo(pathPoints[2],pathPoints[3]);
ctx.lineTo(pathPoints[4],pathPoints[5]);
ctx.closePath();
// stroke the path
// half of the stroke is outside the path
// the outside part of the stroke will survive the clipping that follows
ctx.lineWidth=2;
ctx.stroke();
// make the current path a clipping path
ctx.clip();
// draw the image which will be clipped except in the clipping path
ctx.drawImage(img,x,y);
// restore the unclipped context (==undo the clipping path)
ctx.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Images clipped inside triangular canvas paths</p>
<canvas id="canvas" width=150 height=200></canvas>
<p>Original Images</p>
</body>
</html>
这篇关于一个可重用的功能,使用html5画布将图像剪切成多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!