Reputation:
I have been practicing using Javascript and Canvas and i have come to the issue where i am rendering a shape or two and a few lines to create a custom shape. Now i need to be able to color each one individually however when i use new Image(); on which is meant to the the first shape, the texture is rendered on the last ctx shape drawn.
here is my code:
renderCanvas: function(topLength, heightLength, slant) {
var canvases = Array.from(document.getElementsByClassName("DesignerCanvas"));
for (var canvas of canvases) {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#000';
ctx.lineWidth = 0.5;
// String for Hanging
ctx.beginPath();
ctx.rect(150, 0, 3, 75);
ctx.stroke();
ctx.closePath();
// Top Trimming
ctx.beginPath();
ctx.moveTo( ( 150 - ( topLength / 2 ) ) , 80 );
ctx.quadraticCurveTo( 150 , 70, 150 + ( topLength / 2 ), 80);
ctx.lineTo( 150 + ( topLength / 2 ), 83 );
ctx.quadraticCurveTo( 150 , 73, 150 - ( topLength / 2 ), 83);
ctx.closePath();
ctx.stroke();
// Shade Outter Body
ctx.beginPath();
ctx.moveTo( 150 + ( topLength / 2 ), 83 );
ctx.quadraticCurveTo( 150 , 73, 150 - (topLength / 2), 83);
ctx.lineTo( 150 - (( topLength / 2 ) + slant), heightLength );
ctx.quadraticCurveTo( 150 , ( heightLength - 10 ), 150 + ( (topLength / 2 ) + slant ), heightLength);
ctx.closePath();
ctx.stroke();
// Shade Inner Body
ctx.beginPath();
ctx.moveTo( 150 + ( (topLength / 2) + slant ), heightLength );
ctx.quadraticCurveTo( 150 , (heightLength - 10), 150 - ((topLength / 2) + slant ), heightLength);
ctx.quadraticCurveTo( 150 , (heightLength + 5), 150 + ((topLength / 2) + slant ), heightLength);
ctx.stroke();
ctx.closePath();
// Bottom Trimming
ctx.beginPath();
ctx.moveTo( 150 + ((topLength / 2) + slant ), (heightLength - 3) );
ctx.quadraticCurveTo( 150 , (heightLength - 15), 150 - ((topLength / 2) + slant ), (heightLength - 3));
ctx.lineTo( 150 - ((topLength / 2) + slant ), heightLength );
ctx.quadraticCurveTo( 150 , (heightLength + 5), 150 + ((topLength / 2) + slant ), heightLength);
ctx.closePath();
ctx.stroke();
}
},
init: function () {
console.log("Product Designer: Initialized.");
this.bindActions();
this.renderPage("DesignerTab1", "DesignerPanel1");
}
}
Okay to clarify, my end result should basically the same as how it is now but with the ability to change the texture background of all Paths that i have made. eg First Path String should be able to fill with a image, the next Path Top Trimming should be able to fill with a image etc..
The Problem in my code is that when you place an image to the new Image() then the texture is rendering on the bottom of the entire shape, which is not what i want it should fill the top of the shape only.
Upvotes: 0
Views: 187
Reputation: 3335
The image is loaded asynchronously. The image's onload function is started after the renderCanvas function is completed. When the onload function is executed, the current path will be the last path defined in the renderCanvas function. To draw the image inside the desired path, you need to move the code defining the desired path inside the onload function. For example, change...
// String for Hanging
ctx.beginPath();
ctx.rect(150, 0, 3, 75);
var img = new Image();
img.src = 'image here';
img.onload = function() {
var pattern = ctx.createPattern(this,"repeat");
ctx.fillStyle = pattern;
ctx.fill();
};
ctx.closePath();
to...
// String for Hanging
var img = new Image();
img.src = 'image here';
img.onload = function() {
ctx.beginPath();
ctx.rect(150, 0, 3, 75);
var pattern = ctx.createPattern(this,"repeat");
ctx.fillStyle = pattern;
ctx.fill();
ctx.closePath();
};
Upvotes: 0