P5 SVG imageMode - javascript

I load my mapbox-Link like this and it works:
var mapimg;
function preload () {
mapimg = loadImage('mapbox-LINK');
}
function setup() {
createCanvas(1024,720);
translate(width /2, height / 2);
imageMode (CENTER);
image(mapimg, 0,0);
}
But when I change craeteCanvas() to craeteCanvas( , , SVG) it jumps away and behaves strange. I'm using zenozeng to render the .svg Canvas.
I think it is the imageMode(CENTER) that doesnt work in this enviroment. How can I center my Image again?

You are translating your canvas to center translate(width /2, height / 2); then drawing the image. If you want the image centered, just keep the canvas on its original (0,0), and default imageMode(CORNER)
var mapimg;
function preload () {
mapimg = loadImage('https://api.mapbox.com/styles/v1/foliran/cjnrcb1pm1vbw2rqkbw3o5uog/static/10.4209538,51.1657564,5/1024x720?access_token=pk.eyJ1IjoiZm9saXJhbiIsImEiOiJjam5yZXA0Z2gwNnlmM2twcDJrNnlxdHJkIn0.vSpVuibxadIaVGb4JiPn_w');
}
function setup() {
createCanvas(1024,720,SVG);
// translate(width /2, height / 2); //no need to translate
// imageMode (CORNER); //no need to imageMode, as it's default
image(mapimg, 0,9);
}
I'm not familiar with p5.js-svg but be careful with all the different implications of rendering using the p5.js canvas vs using this svg mode.

Related

FabricJS, change control button image when hover

I am using a custom rotation icon that shows when I select objects, defined as I create the canvas.
function renderRotationIcon(ctx, left, top, styleOverride, fabricObject) {
//#ts-ignore
let size = this.cornerSize
ctx.save()
ctx.translate(left, top)
//#ts-ignore
ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle))
ctx.drawImage(img, -size / 2, -size / 2, size, size)
ctx.restore()
}
However, I would like to change the image img when the user hovers the rotation icon.
I tried this when defining img
img.onmouseover = () => {
img.src = "LibraryHoverTrans.png"
}
As expected, this didn't work, as I suspect that something more specific to fabricJS is needed. I tried searching for a related solution.

Create a image-mask with p5js

Im trying to figure out if its possible to have a blank canvas and then place a image and have it masked by a random shape? That or use a png as mask.
Thank you
M
Yup it is possible and quite trivial with the mask() function on the p5.Image class (it's too bad they don't list this class member functions on the main page of the reference but if you use the search box you'll find these types of things).
Given the image:
And the mask PNG:
You can render the masked image like so:
let img;
let mask;
function preload() {
img = loadImage('https://www.paulwheeler.us/files/windows-95-desktop-background.jpg');
mask = loadImage('https://www.paulwheeler.us/files/Vase-Illusion.png');
}
function setup() {
createCanvas(windowWidth, windowHeight);
img.mask(mask);
noLoop();
}
function draw() {
image(img, 0, 0, height * (img.width / img.height), height)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

How to draw a p5.js circle over an HTML image

I am loading an image into my web app using standard JS and HTML It just just a simple map and my goal is to draw on it using p5.js.
<div id="map">
<img src="Assets/MENA.jpg" class="image" width="1500" height="750">
</div>
function conflictMapMENA() {
this.name="MENA conflict map";
this.id="conflict-map"
this.draw = function() {
var map = document.createElement('img')
map.src = 'Assets/MENA.jpg'
gallery.selectVisual(map);
fill(255, 0, 0);
ellipse(30, 30, 10);
}
}
Inside this.draw = function(){}, I am invoking p5.js library's ellipse() and fill() functions to draw a red circle. This is what it looks like:
But when I try to adjust the coordinates to move the circle over the map, the circles go under it. Is there a way for me to have these two things cooperate without me having to draw the circle in pure JS?
Do you need the image to be in your actual HTML? If not, you can use the loadImage() and image() functions in p5.js:
let myImage;
function setup() {
createCanvas(400, 400);
myImage = loadImage("https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Domestic_Cat_Demonstrating_Dilated_Slit_Pupils.jpg/220px-Domestic_Cat_Demonstrating_Dilated_Slit_Pupils.jpg");
}
function draw() {
image(myImage, 0, 0, width, height);
ellipse(width / 2, height / 2, 100, 100);
}
If you do need your image in your actual HTML, then you can use a combination of CSS and the parent() function to make the image overlap with your sketch:
<body>
<div id="my-canvas"
style="position:absolute;"></div>
<img style="width: 400px; height: 400px;"
src="path/to/image.png" />
<script src="sketch.js"></script>
</body>
function setup() {
const canvas = createCanvas(400, 400);
canvas.parent('my-canvas');
}
function draw() {
ellipse(width / 2, height / 2, 100, 100);
}
Just checked your doubt the background is overlapping the circle because of the depth u can give the depth of the circle greater than the backgroung

How to save a rotated canvas element to a file

I am trying to rotate a large image and save it as a file. I've tried several methods that fail due to the large image size. (OpenCV, Paint Shop Pro, etc).
So, I am trying to do this with javascript. I can draw the image onto a rotated canvas (this works), but when I try to save the canvas to a file, the rotation is lost. It makes sense that this happens, but would like to understand how to capture/extract the rotated state of the canvas before saving?
The client code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function initPage() {
var imageObj = new Image();
imageObj.onload = function() {
// Draw onto rotated canvas
var canvas = document.getElementById('mapCanvas');
context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
// Save image as png
var dt = canvas.toDataURL('image/png');
$.ajax({
type: "POST",
url: "savePNG.php?file=FN617_ROT",
data: {
imgBase64: dt
}
}).done(function(o) {
console.log('saved');
});
};
imageObj.src = 'FN617.png';
}
</script>
<style>
body {
margin: 0;
padding: 0;
}
#mapCanvas {
transform-origin:center center;
transform: rotate(-32.5deg);
}
</style>
</head>
<body onload="initPage();">
<canvas id="mapCanvas" width="9600" height="7200"></canvas>
</body>
</html>
The server code:
<?php
$base64 = str_replace('data:image/png;base64,', '', $_REQUEST['imgBase64']);
$data = base64_decode($base64);
file_put_contents(dirname(__FILE__)."/". $_GET['file'].".png", $data);
?>
When you capture canvas you are capturing the bitmap, not the element. CSS only affects element - as with a plain image, rotating it doesn't actually change the original image in any way.
In order to properly do this, first remove the CSS rotation.
Then apply rotation using the transformation methods of the context. Note here that CSS by default rotates around the center. This is not the case with canvas which rotates by the top left corner, so we need to translate first.
Here are the steps:
// translate to center where the rotation will take place:
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
// rotate (uses radians)
context.rotate = -32.5 * 180 / Math.PI;
// translate back as image is drawn from (0,0)
context.translate(-context.canvas.width * 0.5, -context.canvas.height * 0.5);
// draw image
context.drawImage(imageObj, 0, 0);
Optionally, if image does not correspond with the size of canvas, do the backward translation using the image's size instead.
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
context.rotate = -32.5 * 180 / Math.PI;
context.drawImage(imageObj, -imageObj.width * 0.5, -imageObj.height * 0.5);
Now you can capture canvas with a rotated image.
Note that a canvas of this size may not work in all browsers, and if it does it may not allow you to capture a data-uri of it as some browsers has size limits to those. Just something to have in mind..
You can do this with localStorage, but not with a file for security reasons.

give motion to grass field in canvas

i have created a grass field which is a combination of several small 60x36 images.a grass object is introduced and then drawn on the canvas.now i want to give it motion .the continuous scrolling effect .i made a code for it and it isn't working( the images (the grass field)are not scrolling along the width of the canvas which is the goal of this script).i haven't work much with oop in js. a little discussion on the mistakes i have done will be great
(the image i have used is added to the post)
<html>
<body>
<canvas id="mycanvas"></canvas>
<script>
function makeit(){
var canvas=document.getElementById("mycanvas");
var ctx=canvas.getContext('2d');
var height=500-36;
var xpos=[];
var img=new Image();
img.src="grass.jpg";
drawcanvas();
function drawcanvas(){
canvas.width=600;
canvas.height=500;
canvas.style.border="1px solid black";
}
for(i=0;i<10;i++){
xpos.push(i*60);
}
var grass=function(x,y){
this.x=x;
this.y=y;
this.img=img;
ctx.drawImage(this.img,this.x,this.y);
}
grass.prototype.motion=function(){
for(i=0;i<xpos.length;i++){
xpos[i]--;
if(xpos[i]<=-60){
xpos[i]=canvas.width;
}
ctx.drawImage(this.img,this.x,this.y);
}
}
for(i=0;i<xpos.length;i++){
var grass1=new grass(xpos[i],height);
}
var m=setTimeout(function(){
for(i=0;i<xpos.length;i++){
grass1.motion();
}
},1000);
}
window.onload=makeit;
</script>
</body>
</html>
actual canvas after drawing all the images
In essence, all you need is to create an image pattern then translate and draw it to screen.
An example assuming image has been loaded:
var ph = img.height; // pattern height
var w = canvas.width; // width of canvas/scoll area
var h = canvas.height; // used to calculate y pos.
var x = 0; // scroll position
ctx.fillStyle = ctx.createPattern(img, 'repeat-x'); // pattern
Then in the loop scrolling the grass:
function scroll() {
ctx.translate(x, h - ph); // translate to next position
ctx.fillRect(-x, 0, w, ph); // fill rectangle (fillstyle = pattern)
ctx.translate(-x, -(h -ph)); // translate back for other operations
x--; // scroll speed (here 1 pixel / frame)
requestAnimationFrame(scroll); // loop
}
FIDDLE
Pattern fills are anchored to the coordinate system which is why the translate is necessary. As we translate we also compensate for it using draw position in the opposite direction. This will make the pattern be filled into the same position but at a variable offset which creates the animation effect.
Just note that if you change fillStyle you need to store the pattern in a variable and reinitialize the fill style. If the loop is long-running also limit x so it doesn't overflow. This can be done using w as a condition (or modulo) to reset x to 0.

Categories

Resources