/** CreateImage.js begin **/
// creates a blank image with 2d context
var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}
/** CreateImage.js end **/
var can = createImage(512,512);
document.body.appendChild(can);
var ctx = can.ctx;
const textToDisplay = "Perspective"
const textSize = 80;
ctx.font = textSize+"px arial";
var w = ctx.measureText(textToDisplay).width + 8;
var text = createImage(w + 64,textSize + 32);
text.ctx.fillStyle = "#08F";
text.ctx.strokeStyle = "black";
text.ctx.lineWidth = 16;
text.ctx.fillRect(0,0,text.width,text.height);
text.ctx.strokeRect(0,0,text.width,text.height);
text.ctx.font = textSize+"px arial";
text.ctx.fillStyle = "#F80";
text.ctx.strokeStyle = "Black";
text.ctx.lineWidth = 4;
text.ctx.strokeText(textToDisplay,38,textSize + 8);
text.ctx.fillText(textToDisplay,38,textSize + 8);
// Not quite 3D
// ctx is the context to draw to
// image is the image to draw
// x1,x2 left and right edges of the image
// zz1,zz2 top offset for left and right
// image top edge has a slops from zz1 to zz2
// yy if the position to draw top. This is where the top would be if z = 0
function drawPerspective(ctx, image, x1, zz1, x2, zz2, yy){
var x, w, h, h2,slop, topLeft, botLeft, zDistR, zDistL, lines, ty;
w = image.width; // image size
h = image.height;
h2 = h /2; // half height
slop = (zz2 - zz1)/(x2 - x1); // Slope of top edge
z1 = h2 - zz1; // Distance (z) to first line
z2 = (z1/(h2 - zz2)) * z1 - z1; // distance (z) between first and last line
if(z2 === 0){ // if no differance in z then is square to camera
topLeft = - x1 * slop + zz1; // get scan line top left edge
ctx.drawImage(image,0, 0, w, h,x1, topLeft + yy ,x2-x1, h - topLeft * 2) // render to desination
return;
}
// render each display line getting all pixels that will be on that line
for (x = x1; x < x2; x++) { // for each line horizontal line
topLeft = (x - x1) * slop + zz1; // get scan line top left edge
botLeft = ((x + 1) - x1) * slop + zz1; // get scan line bottom left edge
zDistL = (z1/(h2 - topLeft)) * z1; // get Z distance to Left of this line
zDistR = (z1/(h2 - botLeft)) * z1; // get Z distance to right of this line
ty = ((zDistL - z1)/z2) * w; // get y bitmap coord
lines = ((zDistR - z1)/z2) * w - ty;// get number of lines to copy
ctx.drawImage(image,
ty % w, 0, lines, h, // get the source location of pixel
x, topLeft + yy,1 , h - topLeft * 2 // render to desination
);
}
}
var animTick = 0;
var animRate = 0.01;
var pos = 0;
var short = 0;
function update1(){
animTick += animRate;
pos = Math.sin(animTick) * 20 + 20;
short = Math.cos((pos/40) * Math.PI) * text.width * 0.12 - text.width * 0.12;
ctx.clearRect(0,0,can.width,can.height)
drawPerspective(ctx,text,0,0,text.width,pos,20)
drawPerspective(ctx,text,0,0,text.width+short,pos,textSize + 32 + 30)
requestAnimationFrame(update1);
}
update1();
使用帆布,未必是理想的控制。 SVG在做這類事情方面很出色。 – Keith
@Keith你能指出一個我能得到一個快速創意的來源嗎? –
http://stackoverflow.com/questions/20660085/how-to-stretch-an-image-in-a-svg-shape-to-fill-its-bounds – Keith