答案 0 :(得分:2)
您可以通过这种方式绘制斜边拼图。
destination-in
source-atop
另外,您需要做的是计算每件作品所用图像的偏移量。您还可以将每个部分绘制到单独的画布中,并将画布提取为图像,稍后您可以使用该图像来绘制/显示这些部分。
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
一个非常快速的答案。我相信有人可以改进这一点并欢迎。
功能拍摄图像并返回应用了斜角的新图像。
函数参数
返回图像(作为画布)
使用示例
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;
}