Has anyone here have done clipping an image within an image? I've seen so far about clipping on the canvas but are all regular shapes(rectangle, circle, etc...). It would be nice if some have actually done it.
P.S. with fabric.js or just the regular canvas.
Sure, you can use compositing to draw a second image only where the first image exists:
ctx.drawImage(image1,0,0); // this creates the 'mask'
ctx.globalCompositeOperation='source-in';
ctx.drawImage(image2,0,0); // this image only draws inside the mask
Illustration: House image drawn first and second Grass image is drawn only where house pixels exist:
Example code an a Demo: http://jsfiddle.net/m1erickson/r71d8d8b/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// put the paths to your images in imageURLs[]
var imageURLs=[];
// push all your image urls!
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house100x100.png");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/mower_start.png");
// the loaded images will be placed in images[]
var imgs=[];
var imagesOK=0;
loadAllImages(start);
function loadAllImages(callback){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
callback();
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
function start(){
// the imgs[] array now holds fully loaded images
// the imgs[] are in the same order as imageURLs[]
ctx.drawImage(imgs[0],50,50);
ctx.globalCompositeOperation='source-in';
ctx.drawImage(imgs[1],0,0);
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Second grass image is drawn only where<br>house pixels already existed<br>(Uses 'source-in' compositing)</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Related
I want to use HTML canvas fillRect() to make a block with a diagonal line from upper right to bottom left.
I managed to create a block with a line from upper left to bottom right.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
for(var i = 0; i < 300; ++i) {
ctx.fillRect(i, i, 1, 1);
}
</script>
</body>
</html>
How can I get what I want based on this code?
I managed it using lineTo.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(300, 0);
ctx.lineTo(0, 300);
ctx.moveTo(0, 300);
ctx.lineTo(300, 0);
ctx.stroke();
</script>
</body>
</html>
I have a kendo diagram, in that one shape is already there, I have to add the next shapes, and after that next should be added to the Parent Shape or child Shape based on the condition specified dynamically and shape type will also be specified dynamically.
I have kept a button after clicking on that button, the shape is coming but not dynamically.
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.common.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.rtl.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.silver.min.css"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.2.619/styles/kendo.mobile.all.min.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.2.619/js/kendo.all.min.js"></script>
</head>
<body>
<button id="createBtn">Create Shape</button>
<div id="diagram"></div>
<script>
$("#createBtn").on("click", function(){
//var count=kendo.dataviz.diagram.Shape().count();
//alert(count);
var diagram = $("#diagram").getKendoDiagram();
var shape = new kendo.dataviz.diagram.Shape({
type: "circle",
width: 200,
height: 200,
stroke: {
width: 1,
color: "#red"
},
fill: "#e8eff7",
editable: true
});
var diagram = $("#diagram").getKendoDiagram();
diagram.addShape(shape);
diagram.bringIntoView(diagram.shapes);
});
var Shape = kendo.dataviz.diagram.Shape;
$("#diagram").kendoDiagram();
var diagram = $("#diagram").data("kendoDiagram");
var shape = new Shape({x: 500, y: 100, fill: "red"});
diagram.addShape(shape);
</script>
</body>
</html>
If i pass the shape type and shape location to which it should get bind. It should give an Shape Connected with that specified location.
Create the shape, then connect it.
// Connect new shape to last added shape
var diagram = … ;
var count = diagram.shapes.length;
var lastAddedShape = diagram.shapes[count-1];
var shape = …;
diagram.addShape(shape);
diagram.connect(lastAddedShape, shape);
Using paperjs if I rotate p.view.rotate(update.deg); it is working fine with out issue.
If I refresh the page and call the above function p.view.rotate(update.deg); onload then the view is different. it is displaying a slight zoom.
default image rotation
After reloading the page I am rotating p.view with the previous value. then it is displaying as
Here is my js file
https://github.com/muralibobby35/annotateJs/blob/master/opentok-whiteboardnew.js
I was not able to run your code but I would suggest, for an easier project state preservation, that you use transformations (scale, rotation, ...) through layer rather than through view.
That would allow you to easily export/import your project whithout having to manually restore state by calling view.rotate() like methods on window reload.
Here is a fiddle demonstrating the solution.
It simulates window reload by exporting/importing a project from one canvas to another empty one.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Debug Paper.js</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.11.5/paper-full.min.js"></script>
<style>
html,
body {
margin : 0;
overflow : hidden;
height : 100%;
}
main {
display : flex;
height : 100vh;
}
canvas {
flex : 1;
border : 1px solid;
}
</style>
</head>
<body>
<main>
<canvas id="canvas1" resize></canvas>
<canvas id="canvas2" resize></canvas>
</main>
<script type="text/paperscript" canvas="canvas1">
// draw a square
var rectangle = new Path.Rectangle({
from: view.center - 50,
to: view.center + 50,
fillColor: 'orange'
});
// rotate layer rather than view so transformations are persisted when exporting
project.activeLayer.rotate(30);
// export datas and store them in global variable just for the demo, to simulate a page reload
window.exportedDatas = project.exportJSON();
</script>
<script type="text/paperscript" canvas="canvas2">
// import the exported datas
project.importJSON(window.exportedDatas);
// see that rotation is preserved
</script>
</body>
</html>
I'm trying to add a D3.js liquid fill gauge (http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6) in a Leaflet popup without succeeding.
Here is my code:
var map = L.map('map').setView([47.261491,-1.549244], 16);
var dataCenterIcon = L.icon({
iconUrl: 'images/datacenter-icon.png',
iconSize: [20, 20] // size of the icon
});
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
d3.json("data/datacentersSigma.json",function (data){L.geoJson(data,{
pointToLayer: function (feature,latlng){return L.marker(latlng,{icon:dataCenterIcon});},
onEachFeature : function (feature, layer) {
var div = $('<div class="popupGraph" style="width: 200px; height:200px;"><svg id="gauge"/></svg></div>')[0];
var popup = L.popup().setContent(div);
layer.bindPopup(popup);
// var svg = d3.select(div).select("svg").attr("width", 200).attr("height", 200);
// svg.append("rect").attr("width", 150).attr("height", 150).style("fill", "lightBlue");
loadLiquidFillGauge("gauge",55);
}}).addTo(map);});
d3.json("data/trajetsFibreDCSigma.json",function (data){
L.geoJson(data, {
style: function(feature){return {color : feature.properties.stroke};}
}).addTo(map);
});
<!DOCTYPE html>
<html>
<head>
<title>Yepee</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/leaflet.css" />
<script src="js/leaflet.js"></script>
<script src="js/d3.js"></script>
<script src="js/liquidFillGauge.js"></script>
<script src="js/jquery-1.11.3.min.js"></script>
</head>
<body>
<div id="map" style="width: 800px; height: 600px"></div>
<!-- <svg id="gauge"/>-->
<script src="js/yepee.js" type="text/javascript"></script>
</body>
</html>
When I'm trying to display my map, I can't even see the markers and I've got this error:
TypeError: d3_window(...) is null
I can also load a liquid fill gauge on a svg element which isn't on my map.
I've tried to add just a simple svg square in the popup by following an example (http://jsfiddle.net/2XfVc/132/) and it worked.
The goal is to put that gauge in the leaflet popup and despite searching for a long time, I can't find what the problem is.
Thank you in advance for your answers.
You're trying to initialize the gauge when the actual SVG element isn't added to the DOM yet. Once the popup opens, the content gets added to the DOM, that's when you should initialize the gauge.
// Have same content for all your popups
var content = '<svg id="gauge" width="100" height="100"></svg>'
// Set markers with popup, include content and set value as option
new L.Marker([0, -45]).bindPopup(content, {'value': 33}).addTo(map)
new L.Marker([0, 45]).bindPopup(content, {'value': 66}).addTo(map)
// Catch popup open event
map.on('popupopen', function (e) {
// Initialize the gauge with current popup option's value
loadLiquidFillGauge('gauge', e.popup.options.value);
})
Demo on Plunker: http://embed.plnkr.co/2hMjBt/preview
I have a jsfiddle here to illustrate my question
http://jsfiddle.net/ttmt/DgnLd/1/
It's just a simple button with a hidden div. The button slide toggles the hidden div.
I would like to have div filled with a random color each time it opens.
At the moment it's picking two random colors - when the div is opening and when the finished opening.
How can I stop the second color and just have one.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/3.4.1/build/cssreset/cssreset-min.css">
<style type="text/css">
•{
margin:0;
padding:0;
}
#wrap{
margin:20px;
}
#btn{
width:100px;
height:50px;
background:red;
color:white;
padding:10px;
margin:0 0 50px 0;
}
#infoDiv{
width:500px;
height:300px;
display:none;
}
</style>
</head>
<body>
<div id="wrap">
CLICK
<div id="infoDiv">
</div>
</div>
<script>
$(document).ready(function(){
alert('here');
var color_arr = ['#6faab6','#80c3d1','#888888','#d8e420','#21b4e4','#e4b115','#33ace4'];
$('#infoDiv').hide();
$('#btn').bind('click', function(){
$('#infoDiv').slideToggle('slow', function(){
var ranNum = Math.floor(Math.random()*color_arr.length);
var col = color_arr[ranNum];
$('#infoDiv').css({'background': col});
});
});
});
</script>
</body>
</html>
$(document).ready(function(){
var color_arr = ['#6faab6','#80c3d1','#888888','#d8e420','#21b4e4','#e4b115','#33ace4'];
$('#infoDiv').hide();
$('#btn').bind('click', function(){
var ranNum = Math.floor(Math.random()*color_arr.length);
var col = color_arr[ranNum];
$('#infoDiv:hidden').css({'background': col});
$('#infoDiv').slideToggle('slow');
});
});
Try that -- I've moved your Random color picker out of the SlideToggle callback as that will only run once the slide was finished which from your question I assumed you didn't want.
It also only changes the color of the info div if it's hidden by checking the visible selector, you can read more about that here
Let me know if that works for you