I wanted to draw the circular canvas and wanted to download the canvas with same format. Following is css which i am using
canvas {
width: 20em;
height: 20em;
border-radius: 50%;
background-color: red;
border: 4px solid #fff;
box-shadow: 0 0 0 5px red;
}
At present i have just apply the css to canvas to look a like it will not print same in fabric js.
Is there any possible way? Because i am trying to create circular canvas and add text and wanted to print same canvas with text and styling.
Edit:
Is it possible to draw the circle with same styling in fabric.js
You cannot really have a circular canvas in fabricjs, but you can clip a canvas to look like a circle.
i did a circle that has radius half of the canvas, and is positioned in the center.
Effect is same as your example.
Look the fiddle:
var canvas = new fabric.Canvas('c');
canvas.clipTo = function(ctx) {
ctx.beginPath();
ctx.arc(200,200,200,0,2*Math.PI);
}
canvas.backgroundColor = 'blue';
var rect = new fabric.Rect({width: 100, height:100, fill:'red', top:30, left:30});
canvas.add(rect);
canvas.renderAll();
<script src="http://www.fabricjs.com/lib/fabric.js"></script>
<canvas id="c" width="400" height="400" ></canvas>
Related
PaperJS has documentation how to setup the canvas in to resize the canvas when the window changes dimensions. The same solution can be found in this SO answer.
The problem with this approach is that it will change the coordinates while drawing, and also it will be resizing the canvas, which can be less performant.
I would like to scale the canvas without changing the width of the element. The problem I found is that PaperJS adds a width and height to the canvas element in runtime, and I could not find a way to stop this behaviour, this will result the calculated value when the setup is done, and could be for instance:
width="817" height="817"
Here is an example of a HTML Canvas that behaves the way I intend, and also the PaperJS version which does not scale. Resize the browser window to see how the example in the bottom will stretch the canvas content, but keeping the circle in the center of the canvas.
I would like to find a way to configure PaperJS that would work in the same way, without having to change the draw coordinates inside a onResize handler.
Is this possible?
const SIZE = 150;
window.onload = () => {
// --- Paperjs ---
const canvas = document.getElementById('paper');
paper.setup(canvas);
// draw circle in the center of the view
const c = new paper.Path.Circle(new paper.Point(SIZE, SIZE), SIZE);
c.strokeColor = 'white';
c.strokeWidth = 3;
// --- END Paperjs ---
// --- Canvas ---
const ctx = document.querySelector("#canvas").getContext("2d");
ctx.strokeStyle = "#FFFFFF";
ctx.fillStyle = "white";
ctx.lineWidth = 3;
ctx.beginPath();
// x, y, width
ctx.arc(SIZE, SIZE, SIZE, 0, 2 * Math.PI);
ctx.stroke();
// --- END Canvas ---
}
.wrapper {
margin-left: 10vw;
width: 80vw;
border: 1px solid cyan;
}
.responsive-canvas {
background-color: silver;
max-width: inherit;
max-height: inherit;
height: inherit !important;
width: inherit !important;
object-fit: contain;
}
* {
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.17/paper-full.min.js"></script>
<h2>PaperJS</h2>
<div class="wrapper">
<canvas id="paper" class="responsive-canvas" width="300px" height="300px"></canvas>
</div>
<h2>Canvas</h2>
<div class="wrapper">
<canvas class="responsive-canvas" id="canvas" width="300px" height="300px"></canvas>
</div>
could you tell me what is the problem with the text on my canvas? I tried to change the text size if I make it bigger it looks fine but if I make it smaller it looks weird. I'm not sure what exactly affect the text; I tried to play with font property but with no result, whenever I make the font smaller I got the result like in the snippet below
here is my code
(function(){
function init(){
var canvas = document.getElementsByTagName('canvas')[0];
var c = canvas.getContext('2d');
var animationStartTime =0;
c.fillStyle = 'white';
c.font = 'normal 10pt';
var textarray = 'you can live a beatiful life with a postive mind';
var j=1;
//time - next repaint time - HRT
function draw(time){
c.fillText(textarray.substr(0,j),10,70);
if(time - animationStartTime > 100){
animationStartTime = time;
j++;
}
if( j <= textarray.length){
requestAnimationFrame(draw); // 17ms
}
}
function start(){
animationStartTime = window.performance.now();
requestAnimationFrame(draw);
}
start();
}
//invoke function init once document is fully loaded
window.addEventListener('load',init,false);
}()); //self invoking function
#canvas{
overflow:hidden;
background-image: url('http://linux2.gps.stthomas.edu/~algh3635/practice/proj/img/img4.jpeg');
background-repeat: no-repeat;
background-size: cover;
}
canvas {
width:100%;
height:80vh;
left: 0;
margin: 0;
padding: 0;
position: relative;
top: 0;
}
<div id="canvas">
<div class="row">
<div class="col-lg-12 text-center" >
<canvas >
</canvas>
</div>
</div>
</div>
When you fillText on the canvas, it stops being letters and starts being a letter-shaped collection of pixels. When you zoom in on it, the pixels become bigger. That's how a canvas works.
When you want the text to scale as a vector-based font and not as pixels, don't draw them on the canvas. You could create HTML elements instead and place them on top of the canvas using CSS positioning. That way the rendering engine will render the fonts in a higher resolution when you zoom in and they will stay sharp. But anything you draw on the canvas will zoom accordingly.
But what I would recommend for this simple example is just doing it in html, css, and javascript like so:
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
$(function () {
showText("#text", "you can live a beatiful life with a postive mind", 0, 100);
});
#canvas{
position: relative;
width: 100%;
height: 80vh;
overflow:hidden;
background-image: url('http://linux2.gps.stthomas.edu/~algh3635/practice/proj/img/img4.jpeg');
background-repeat: no-repeat;
background-size: cover;
}
#text {
position: absolute;
top: 50%;
left: 20px;
color: #fff;
font-size: 20px;
}
<div id="canvas">
<p id="text"> </p>
</div>
I'll leave it up to you to position the text and whatnot but you can see in this example that you can make the text as small, or as big, as you want.
However
...if you still absolutely need it to be a canvas then the following example works. It works because the canvas is not being stretched by css, the width and height are predefined.
The canvas element runs independent from the device or monitor's pixel ratio.
On the iPad 3+, this ratio is 2. This essentially means that your 1000px width canvas would now need to fill 2000px to match it's stated width on the iPad display. Fortunately for us, this is done automatically by the browser. On the other hand, this is also the reason why you see less definition on images and canvas elements that were made to directly fit their visible area. Because your canvas only knows how to fill 1000px but is asked to draw to 2000px, the browser must now intelligently fill in the blanks between pixels to display the element at its proper size.
I would highly recommend you read this article from HTML5Rocks which explains in more detail how to create high definition elements.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.font = "12px Arial";
ctx.fillText("Hello World",10,50);
#canvas{
position: relative;
overflow:hidden;
background-image: url('http://linux2.gps.stthomas.edu/~algh3635/practice/proj/img/img4.jpeg');
background-repeat: no-repeat;
background-size: cover;
}
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas" width="800" height="500"
style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
</body>
</html>
This question already has answers here:
Canvas is stretched when using CSS but normal with "width" / "height" properties
(10 answers)
Closed 5 years ago.
I have a canvas tag without width and height attributes. The canvas has inline width and height. Now when I apply linearGradient over it, it doesn't cover whole canvas. Demo:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var gradient1 = ctx.createLinearGradient(0, 0, 150, 0);
gradient1.addColorStop(0, "#123456");
gradient1.addColorStop(1, "#654321");
ctx.fillStyle = gradient1;
ctx.fillRect(0, 0, 150, 100);
canvas {
border: 1px dotted red;
}
<canvas id="canvas" style="width: 150px; height: 100px;"></canvas>
Question1: Why doesn't whole 150px of canvas get covered? And if I add width="150" and height="100" attributes on canvas tag, why does it then fill whole canvas?
Question 2: In below script c.width returns 300px not 150px, why?
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
console.log(c.width);
console.log(c.height);
canvas {
border: 1px dotted red;
}
<canvas id="canvas" style="width: 150px; height: 100px;"></canvas>
Question3: Is this behavior due to something similar to svg viewBox?
I'm not sure why the inline styling isn't working, but if you change your canvas element to this:
<canvas id="canvas" width="150px" height= "100px;"></canvas>
Then the console logs the correct value and the gradient fills the canvas. :) I don't know why you can't use the other method, but I do know that everywhere I've seen I think everyone who uses the html canvas specifies the width and height in this way. (unless they specify it in the javascript)
Here's a pen of your working code: https://codepen.io/Awesomennjawarrior/pen/zwmmPY
I want to stretch the font of a canvas Text object. How can I do this?
Example (before):
Example (after):
How could I implement this?
You can use scaleX to "squish" the text by scaling the text:
// "squish" the text to 60% of its original width
scaleX:0.60
Example code and a Demo
var canvas = new fabric.Canvas('canvas');
var myText = new fabric.Text('NEW TEXT',{
left: 50,
top: 60,
});
canvas.add(myText);
var mySquishedText = new fabric.Text('NEW TEXT',{
left: 50,
top: 100,
scaleX:0.60,
});
canvas.add(mySquishedText);
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<canvas id="canvas" width=300 height=300></canvas>
[Update: #AndreaBogazzi adds that scaleX is better handled than the matrix ops]
I have the following html and css for a Tetris game I am making:
html
<div id = "TetrisHolder">
<canvas id = "TetrisCanvas" style = "width:400px; height:500px"></canvas>
</div>
css
div#TetrisHolder {
display: table;
margin:auto;
background: black;
border: solid black 3px;
}
canvas#TetrisCanvas {
background: url(Resources/bg.png) no-repeat center;
background-size: cover ;
}
When I attempt to resize it with the following javascript, nothing happens. I have seen most other StackOverflow questions about resizing DOM elements answered this way, however it does not work for me. what am I missing?
note: I am aware that I will need to redraw what is on the canvas but all I want right now is to resize it.
js
function resize() {
canvas = document.getElementById("TetrisCanvas");
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth*0.6;
canvas.height = window.innerHeight*0.6;
}