如何在画布html5中创建一个具有斜角效果的拼图块

时间:2016-05-09 12:12:47

标签: javascript html5 canvas

我正在尝试创建具有图像效果的拼图,但我无法通过。

任何人都可以帮我如何用canvas和html5创建作品。

enter image description here

谢谢

2 个答案:

答案 0 :(得分:2)

您可以通过这种方式绘制斜边拼图。

  • 绘制要用于正确放置的部分的图像部分
  • 为拼图构建路径
  • 使用复合模式destination-in
  • 打出作品
  • 将rect / bounding box添加到路径
  • 使用复合模式source-atop
  • 定义暗阴影和填充
  • 移动阴影并将颜色更改为明亮,再次填充

result

另外,您需要做的是计算每件作品所用图像的偏移量。您还可以将每个部分绘制到单独的画布中,并将画布提取为图像,稍后您可以使用该图像来绘制/显示这些部分。

实施例

var ctx = c.getContext("2d"), img = new Image;
img.onload = demo;
img.src = "https://pixeloceanblog.files.wordpress.com/2016/05/pres_frontcorner.jpg";

function demo() {
ctx.translate(-20,-90);  // just to compensate for demo puzzle piece position

// 1) Draw puzzle pieze graphics
ctx.drawImage(this, -220, -110);

// 2) build path for puzzle piece
puzzlePath(ctx);

// 3) Punch out piece
ctx.globalCompositeOperation = "destination-in";
ctx.fill();

// 4) Add rect to make stencil
ctx.rect(0, 0, c.width, c.height);

// 5) Build dark shadow
ctx.shadowBlur = 7;
ctx.shadowOffsetX = -7;
ctx.shadowOffsetY = -7;
ctx.shadowColor = "rgba(0,0,0,0.8)";

// 6) Draw stencil with shadow but only on non-transparent pixels
ctx.globalCompositeOperation = "source-atop";
ctx.fill();

// 7) move shadow and change color to white transparent
ctx.shadowOffsetX = 7;
ctx.shadowOffsetY = 7;
ctx.shadowColor = "rgba(255,255,255,0.8)";
ctx.fill();

// DONE!

// Puzzle path for demo
function puzzlePath(ctx) {
ctx.beginPath();
ctx.moveTo(36.421871,256.82809);
ctx.bezierCurveTo(36.981411,272.02753,42.075181,289.07672,52.984371,298.17184);
ctx.bezierCurveTo(81.172101,311.4011,68.157281,279.26413,87.671871,275.48434);
ctx.bezierCurveTo(107.18646,271.70455,108.26562,294.39059,108.26562,294.39059);
ctx.lineTo(108.26562,294.39059);
ctx.lineTo(108.26562,392.14059);
ctx.bezierCurveTo(108.26562,392.14059,205.20313,392.01559,205.20312,392.01559);
ctx.bezierCurveTo(205.20312,392.01559,227.88915,390.93642,224.10937,371.42184);
ctx.bezierCurveTo(221.03829,355.56624,199.23133,361.18908,198.26562,348.73434);
ctx.bezierCurveTo(198.04276,345.86017,198.94138,342.01954,201.42187,336.73434);
ctx.bezierCurveTo(210.51699,325.82514,227.56618,320.73138,242.76562,320.17184);
ctx.bezierCurveTo(248.37657,319.96528,253.65356,320.45514,258.26562,321.42184);
ctx.bezierCurveTo(258.47031,321.44665,258.68579,321.48913,258.89062,321.51559);
ctx.bezierCurveTo(272.00503,323.2095,285.30842,328.27739,292.98437,337.48434);
ctx.bezierCurveTo(306.21364,365.67208,274.07665,352.65725,270.29687,372.17184);
ctx.bezierCurveTo(267.54294,386.39004,278.77521,390.78229,285.10937,392.14059);
ctx.lineTo(388.01562,392.14059);
ctx.lineTo(388.01562,290.54684);
ctx.bezierCurveTo(389.23388,284.34562,393.50469,272.30575,408.14062,275.14059);
ctx.bezierCurveTo(427.65522,278.92038,414.64038,311.02611,442.82812,297.79684);
ctx.bezierCurveTo(452.03508,290.1209,457.10296,276.8175,458.79687,263.70309);
ctx.bezierCurveTo(458.82334,263.49827,458.86581,263.28278,458.89062,263.07809);
ctx.bezierCurveTo(459.85733,258.46605,460.34718,253.18904,460.14062,247.57809);
ctx.bezierCurveTo(459.58109,232.37865,454.48732,215.32946,443.57812,206.23434);
ctx.bezierCurveTo(415.3904,193.00508,428.40521,225.14205,408.89062,228.92184);
ctx.bezierCurveTo(389.37605,232.70164,388.29687,210.01559,388.29687,210.01559);
ctx.lineTo(388.01562,112.82809);
ctx.bezierCurveTo(388.01562,112.82809,289.76561,113.4531,289.76562,113.45309);
ctx.bezierCurveTo(289.76562,113.45309,267.07957,114.53227,270.85937,134.04684);
ctx.bezierCurveTo(274.63916,153.56143,306.77612,140.54662,293.54687,168.73434);
ctx.bezierCurveTo(284.45175,179.64354,267.40256,184.73731,252.20312,185.29684);
ctx.bezierCurveTo(246.59217,185.5034,241.31517,185.01355,236.70312,184.04684);
ctx.bezierCurveTo(236.49843,184.02203,236.28293,183.97956,236.07812,183.95309);
ctx.bezierCurveTo(222.96371,182.25918,209.6603,177.1913,201.98437,167.98434);
ctx.bezierCurveTo(199.50388,162.69914,198.60526,158.85851,198.82812,155.98434);
ctx.bezierCurveTo(199.79383,143.5296,221.56954,149.15245,224.64062,133.29684);
ctx.bezierCurveTo(228.16732,115.08894,209.3009,113.03555,206.67187,112.82809);
ctx.lineTo(108.26562,112.82809);
ctx.lineTo(108.26562,214.98434);
ctx.bezierCurveTo(106.78368,221.38993,102.27374,231.94857,88.421871,229.26559);
ctx.bezierCurveTo(68.907281,225.48581,81.922111,193.38007,53.734371,206.60934);
ctx.bezierCurveTo(44.527431,214.28529,39.459541,227.58868,37.765621,240.70309);
ctx.bezierCurveTo(37.739161,240.90792,37.696681,241.1234,37.671871,241.32809);
ctx.bezierCurveTo(36.705171,245.94014,36.215311,251.21714,36.421871,256.82809);
}
}
body {background:#777}
<canvas id=c width=500 height=500></canvas>

答案 1 :(得分:2)

使用蒙版来应用内斜角FX

一个非常快速的答案。我相信有人可以改进这一点并欢迎。

功能拍摄图像并返回应用了斜角的新图像。

函数参数

  • 图像。要应用斜角的图像
  • 量。斜角0的强度为无,1为满
  • OFFSETX
  • OFFSETY。斜角的偏移量。
  • 模糊。模糊。必须大于或等于0
  • 类型。斜角的类型为字符串,ethier,'shadow','light'或作为颜色,例如 '黑色'

返回图像(作为画布)

使用示例

var image = new Image();
image.src = "imageURL.png";
image.onload = function(){
    var bevImage = innerBevel(this,0.5,-4,-4,4,"shadow"); // bevel shadow
    bevImage = innerBevel(bevImage,0.5,4,4,4,"light"); // bevel highlight
    if(typeof ctx !== 'undefined'){
        ctx.drawImage(bevImage,0,0); // draw the image to the current context
    }
}

功能

function innerBevel(image, amount, offsetX, offsetY, blur, type){
    var c = document.createElement("canvas");
    c.width = image.width + (Math.abs(offsetX) + blur) * 2; // cludge could be a better fit
    c.height = image.height + (Math.abs(offsetY) + blur) * 2; // cludge could be a better fit
    var ctx1 = c.getContext("2d");
    ctx1.fillRect(0,0,c.width,c.height); // fill pixels
    // create the shadow mask
    ctx1.globalCompositeOperation = "destination-out";
    ctx1.drawImage(image, Math.abs(offsetX)+blur, Math.abs(offsetY)+blur); // create inverse mask
    // create second image.
    var c1 = document.createElement("canvas");    
    c1.width = image.width; 
    c1.height = image.height;    
    var ctx2 = c1.getContext("2d");
    // copy the image
    ctx2.drawImage(image,0,0);
    // create the shadow and draw it as a shadow from the mask
    ctx2.save();
    if(type === "shadow"){
        ctx2.shadowColor = "black";
        ctx2.globalCompositeOperation = "multiply";
    }else
    if(type === "light"){
        ctx2.shadowColor = "White";
        ctx2.globalCompositeOperation = "lighter";
    }else{
        ctx2.shadowColor = type;
    }
    ctx2.globalAlpha = amount;
    ctx2.shadowOffsetX = offsetX;
    ctx2.shadowOffsetY = offsetY;
    ctx2.shadowBlur = blur;
    ctx2.drawImage(c,-(Math.abs(offsetX) + blur), -(Math.abs(offsetY) + blur)); // create inverse mask
    ctx2.restore(); // remove the shadow settings



    // mask out the unwanted pixels
    ctx2.globalCompositeOperation = "destination-out";
    ctx2.drawImage(c,-(Math.abs(offsetX) + blur), -(Math.abs(offsetY) + blur)); 
    ctx2.globalCompositeOperation = "source-over";
    return c1; // return the new beveled image;
}