2014-09-06 5 views
4

Удовлетворение названия сообщения может потребоваться для редактирования, но пока я не знаю, где проблемы. Я читал страницы и отвечал на подобные вопросы, здесь и в других местах. Один ответ переполнения стека особенно близок, но я этого не понимаю.Функция многократного копирования изображений в многоугольники с использованием холста html5

Я хочу функцию, чтобы нарисовать полигоны на холсте в нужных координатах и ​​заполнить их некоторым фоновым изображением, загруженным из файла (достаточно большим, чтобы не было необходимости в черепице). Треугольники были бы хороши для теста. По-видимому, я должен использовать drawImage и клип, а чтобы предоставить полигону границу, я могу использовать один и тот же путь для клипа и штриха. Также, видимо, я должен хранить порядка

- define path 
- save 
- clip 
- drawImage 
- restore 
- stroke. 

Также читайте где-нибудь, что достаточно загрузить изображение один раз. (Если uou хотите, чтобы я цитирую источники для всех этих предположений, я буду искать, где я их видел. Большинство из них на переполнение стека)

HTML, является иначе пустой

<body onload = "main();"></body> 

Первый подход, делая вид, что браузер будет ждать изображения для загрузки:

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(); 


} 

Это привлекает все три треугольника, но нет вырезанных изображений.

Вторая попытка, с DrawImage внутри 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(); 
    } 

} 

Это один делает обратить обрезанное изображение, но только один треугольник, последний. Просто комментирование сохранения и восстановления не помогает.

Итак, я не понимаю, как загружать изображения, сохранять, восстанавливать и, возможно, миллионы других вещей. Где будут ошибки?

ответ

5

Я вижу, вы уже понимаете основы вырезки:

  • сохранить контекст, определить путь, клип, DrawImage, восстановить контекст.

  • вы можете погладить после восстановления, если вы хотите, чтобы штрих слегка перекрывал обрезанное изображение.

  • вы можете обрезать перед обрезкой, если вы не хотите, чтобы удар перекрывал обрезанное изображение.

enter image description here

Вот пример кода и демо: 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> 
+0

Благодаря ориентировочно. Я должен обработать его :) – user3334085

+1

На данный момент я получил ширину линии шириной 2 пикселя, половина из которых выживет. Но обратный вызов я должен прочитать, прежде чем я смогу попробовать это сам и спасибо вам должным образом :) – user3334085

+0

Похоже, что start() является основным. Мы просто поместили всю программу в загрузчик изображений? Пожалуйста, это настоящий вопрос, а не риторический. – user3334085

 Смежные вопросы

  • Нет связанных вопросов^_^