paper.js vector slow performance - javascript

I've been trying to get this fairly simple program to work and am running into performance problems.
I'm trying to make thousands of tiny colored dots on a canvas. Creating so many new paths is slowing down my computer before I am able to get the amount that I want on the canvas, and then crashes when I try to export the canvas as an SVG. I looked into using symbols, but I need the colors of each dot to be different.
The goal is for every color and position to be completely random and unique, and to have the dots completely cover the canvas. The canvas will eventually need to be printed 55 inches by 75 inches, so I will want the circles to be of high enough resolution that they don't look pixellated when printed. This can mean either being able to export to a high enough raster resolution or to export to a vector.
I'm using paper.js because I figured that it would be best to render the dots as vector graphics so that I can print them at high quality when I need to, but is there a better way to do this?
Thanks.
the html below is everything (except for the paper.js library).
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/style.css">
<!-- Load the Paper.js library -->
<script type="text/javascript" src="js/paper.js"></script>
<!-- Define inlined PaperScript associate it with myCanvas -->
<style type="text/css">
html,
body {
margin: 0;
overflow: hidden;
height: 100%;
}
/* Scale canvas with resize attribute to full size */
canvas[resize] {
width: 550px;
height: 750px;
background-color: #39ff14;
}
</style>
<script type="text/paperscript" canvas="myCanvas">
paper.install(window);
tool.fixedDistance = .1;
var layer = project.activeLayer;
function onMouseMove(event) {
var radius = (1 * Math.random()) + .5;;
var path = new Path.Circle({
center: Point.random() * view.size,
radius: radius,
fillColor: "#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);}),
})
}
// START DOWNLOAD BUTTON &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
function downloadDataUri(options) {
if (!options.url)
options.url = "http://download-data-uri.appspot.com/";
$('<form method="post" action="' + options.url
+ '" style="display:none"><input type="hidden" name="filename" value="'
+ options.filename + '"/><input type="hidden" name="data" value="'
+ options.data + '"/></form>').appendTo('body').submit().remove();
}
$('#export-button').click(function() {
var svg = project.exportSVG({ asString: true });
downloadDataUri({
data: 'data:image/svg+xml;base64,' + btoa(svg),
filename: 'export.svg'
});
});
// END DOWNLOAD BUTTON &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
</script>
</head>
<body>
<canvas id="myCanvas" resize></canvas>
<input type="button" value="Download as SVG" id="export-button">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!-- <script src="js/scripts.js"></script> -->
</body>
</html>

Related

Resize/Scale controls in paper js like in fabric js

my question is is there someone out there who managed to get a scaling/resizing like this: http://fabricjs.com/controls but in paper js?
Would appreciate some help or directions how to do that.
EDIT: You see the quadrats in the link, when you pull them the object gets sized in that direction. For example when I pull right side then only right side of object is expanded (in other word the object is scaled horizontally).
That behavior I'm looking for, when I pull an object on one side then it should expand in that side AND I also want to do that when the object have some rotation (e.g. 20° from x axis)
You have to listen to a slider change event, then update your item size accordingly.
Here is a fiddle demonstrating the solution.
<!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.8/paper-full.min.js"></script>
<style>
html,
body {
margin : 0;
overflow : hidden;
height : 100%;
}
canvas[resize] {
width : 100%;
height : 100%;
}
div {
position : fixed;
top : 15px;
left : 15px;
}
</style>
</head>
<body>
<canvas id="canvas" resize></canvas>
<div>
<p>move the slider and see the circle scale change</p>
<input type="range" min="1" max="5" step="0.5" value="1">
</div>
<script>
// setup paper
paper.setup('canvas');
// draw a circle
const circle = new paper.Path.Circle({
center: paper.view.center,
radius: 50,
fillColor: 'orange',
// make sure matrix is not applied so we can easily use scaling property
applyMatrix: false
});
// on slider value change
$('input').change(function() {
const value = $(this).val();
// update circle scale
circle.scaling = value;
});
</script>
</body>
</html>

how to change image when scrolling webpage [html, javascript]

Hi i need to modify java script that will by changing fixed image.
In for example:
when page is loaded then image will by on right site. Next after scrolling down page image should be changed to next one for each e.g. 100px. Images need to by loaded from image list or something similar.
I have found java script that make something similar to this. [Instead of creating images of numbers i need to load my own images]
<!DOCTYPE html>
<html>
<head>
<style>
html,body {
height: 400%;
background: white;
width: 100%;
}
.show {
width: 100px;
height: 100px;
position: fixed;
top: 300px;
right: 20px;
background: lime;
}
</style>
</head>
<body>
<img class="show" alt="0" src="img0.jpg" />
Text,Text,Text,Text,Text,Text,Text,Text,Text,Text,Text
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
</script>
<script type="text/javascript" src="jquery.easing.1.3.js"></script>
<script type="text/javascript">
var lastI
$(window).scroll(function() {
var scrollTop = $(this).scrollTop()
console.log(scrollTop)
var i = (scrollTop / 10).toFixed(0)
if (i !== lastI)
$(".show").attr({
"src": "img" + i + ".jpg",
"alt": i
})
lastI = i
})
</script>
</body>
</html>
Update:09.11.2017
Ok, I manage this code to work. What should I do it was to setup right path to image files like in my case ("src": "test/" + i + ".jpg",) where my images are in "test" folder, and change names of images [1.jpg, 2.jpg and so on].
You can easyli change your image with Native scroll event, without using JQuery :
You can see how to use native scroll event here
<body>
<!-- This is an image with a 'show' id -->
<img id="show" alt="0" src="img0.jpg" />
<script type="text/javascript">
/* this capture the `scroll event`*/
window.addEventListener('scroll', function(e) {
/* This generate a image name in case with scroll position (ex img1.jpg) */
let bgImage = 'img' + (window.scrollY / 10 ).toFixed(0) + '.jpg';
/* This specify the path where are your images list */
let bgImagePath = '../images/' + bgImage;
/* This get your element (img) with id `show` and change this background image by the path include in `bgImagePath` variable */
document.getElementById('show').style.backgroundImage = bgImagePath;
});
</script>
</body>
Native background image explain here
Native getElementById explain here
This sample of code do not use JQuery :) Just native Javascript : you van remove this lines in your code :
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js">
</script>
<script type="text/javascript" src="jquery.easing.1.3.js"></script>
Hope I help you.
I'am not sure, try this one:
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 100) {
$('.Classname').css("background-image","../images/image.png");
} else {
$('.Classname').css("background-image","none");
}
});

SVG quality loss during scaling

I'm using fabricjs to add an animated sprite to my canvas. Unlike in the demo on the fabricjs website I am using an .svg sprite not .png, so it should scale without quality loss.
However when I try and scale up the svg sprite the quality loss is huge. I have tested the sprite as a static object and it scales without any issues with the quality.
Video: https://streamable.com/ya5a
Here's an example, the top image is the sprite with it's default size and below that I have increased it's size and you can see the edges are nasty.
What could be causing the svg to have quality issues when scaling as an animated sprite?
Here is the sprite (crude test image) http://imgh.us/sprite1_2.svg
HTML/JS
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="http://fabricjs.com/lib/fabric.js"></script>
<script src="http://fabricjs.com/js/sprite.class.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<canvas id="canvas" width="500" height="300" style="border:1px solid #444;"></canvas>
<div id="add">Click here to add Animated SVG sprite</div>
<script>
var canvas = this.__canvas = new fabric.Canvas('canvas');
var src1 = "img/sprite1_2.svg";
$("#add").click(function(){
fabric.Sprite.fromURL(src1, createSprite(1),{"width":50,"height":72});
});
function createSprite(i) {
return function(sprite) {
sprite.set({
left: i * 100 + 50,
top: i * 100 + 50,
hasBorders: false,
padding: 0,
});
canvas.add(sprite);
setTimeout(function() {
sprite.play();
}, fabric.util.getRandomInt(1, 10) * 100);
};
}
(function render() {
canvas.renderAll();
fabric.util.requestAnimFrame(render);
})();
</script>
</body>
</html>
(I've found the only way I can get this demo to work is in FF and if the svg is hosted locally, due to SecurityError. Which stopped me making a working fiddle/jsbin)

html5 canvas javascript copy picture

I have a html5 page. It uses JQuery and sketch.js (for free drawing). I am NOT going to connect it to any web server. At this moment, I would like to be use this javascript as desktop application. My purpose is to copy image from one canvas to the other canvas in the same page. After draw something by free hand, I could see url is copied to textarea, but no picture after clicking Show URL link. Could someone give me hints how to make an copy of image from one canvas to the other?
/1/ Source codes, one need to add html tag in the beginning, do not forget <>
<head>
<title>sketch and free hand drawing</title>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js">
</script>
<![endif]-->
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="image/png"/>
<script src="js/jquery-1.11.0.min.js"></script>
<script src="js/sketch.js"></script>
/2/One need to add /head above. do not forget <>
<body>
<script>
function toDo(){
console.log(document.getElementById("colors_sketch").toDataURL("image/png"));
document.getElementById("cvs").value=document.getElementById("colors_sketch").toDataURL("image/png");
document.getElementById("txt").value=document.getElementById("colors_sketch").toDataURL("image/png");
}
</script>
<div class="tools">
Download
</div>
<div class="tools">
show URL
</div>
<textarea id="txt"></textarea>
<hr/>
<canvas id="colors_sketch" width="800" height="300">hello</canvas>
<hr/>
<canvas id="cvs" width="800" height="300"></canvas>
<script type="text/javascript">
$(function() {
$.each(['#f00', '#ff0', '#0f0', '#0ff', '#00f', '#f0f', '#000', '#fff'], function() {
$('#colors_demo .tools').append("<a href='#colors_sketch' data-color='" + this + "' style='width: 10px; background: " + this + ";'></a> ");
});
$.each([3, 5, 10, 15], function() {
$('#colors_demo .tools').append("<a href='#colors_sketch' data-size='" + this + "' style='background: #ccc'>" + this + "</a> ");
});
$('#colors_sketch').sketch();
});
/3/ one need to add /script above and /body above and /html above do not forget <>
To move an image from one canvas to another, you can simply use drawImage
destinationContext.drawImage(sourceCanvas,0,0);
The pixels from the source canvas will be drawn onto the destination canvas.
A Demo: http://jsfiddle.net/m1erickson/2hb56/
I tried modifying your code, but it appears you also have a design issue.
SketchJS will erase your copied image in preparation for it's own drawings (the copied image is erased).
Example code copying pixels from one canvas to another:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script src="http://code.jquery.com/jquery.min.js"></script>
<script src="sketch.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
// get references to canvases and contextx
sourceCanvas=document.getElementById("source");
sourceContext=sourceCanvas.getContext("2d");
destinationCanvas=document.getElementById("destination");
destinationContext=destinationCanvas.getContext("2d");
// draw a test image into the source canvas
var testImg=new Image();
testImg.onload=function(){
sourceContext.drawImage(testImg,0,0);
}
testImg.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png";
// when the button is clicked
// copy the source canvas onto the destination canvas
$("#copy").click(function(){
destinationContext.drawImage(sourceCanvas,0,0);
})
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="source" width=256 height=256></canvas><br>
<button id="copy">Copy canvas above to canvas below</button><br>
<canvas id="destination" width=256 height=256></canvas>
</body>
</html>

having an image thumbnail size exactly across browser

I'm trying to come up with a script that will have a number of thumbnails across (in width) the browser. I want it to be able to be flush and not have gaps on the sides. The thumbnails should always be the same size, and I'm guessing that the only way is the change the spacing between each image. But can someone help me out? Let me know if my question is unclear.
EDIT: here's an example: http://www.beautyineverything.com/
Thank you!
Something like this?
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<title>sandbox</title>
<meta http-equiv='content-type' content='text/html; charset=UTF-8'/>
<script type='text/javascript' src='js/jquery-1.6.1.min.js'></script>
<script type='text/javascript'>
var MAX_IMAGE_WIDTH = 240;
$(function(){
$(window).resize(resizeImages).resize();
});
function resizeImages() {
var containerWidth = $('.imageContainer').innerWidth();
var numberOfImages = Math.ceil(containerWidth / MAX_IMAGE_WIDTH);
var imageWidth = Math.ceil(containerWidth / numberOfImages);
var imageWidthLast = containerWidth - (numberOfImages - 1) * imageWidth;
$('.imageContainer .image').css('width', imageWidth);
$('.imageContainer .image:nth-child(' + numberOfImages + 'n)').css('width', imageWidthLast);
$('.imageContainer .image').each(function(){
$(this).text($(this).innerWidth());
});
}
</script>
<style type='text/css'>
.imageContainer {
border:1px solid black;
overflow:hidden;
}
.image {
width:160px;
height:160px;
float:left;
}
</style>
</head>
<body>
<div class='imageContainer'>
<?php
for ( $n = 10; $n < 30; ++$n) {
$backgroundColor = '#' . sprintf('%02x%02x%02x', $n * 8, $n * 8, $n * 8);
echo "<div class='image' style='background-color:{$backgroundColor};'></div>";
}
?>
</div>
</body>
</html>
Resizing images could be written in a bit smarter way so that instead of 223+223+223+223+223+223+223+216 they would be 223+222+222+222+222+222+222+222. For this, width of each column should be calculated individually, so that widths of columns vary only by 1px max.
This might sound primitive but tables were designed for something like this only.
one solution is to have a table and put your images as background-image of the cells. (or put it inside and give it a height and width 100%) Its is easy to keep control over the cell size and margins/padding.. that is why they were so popular for structural stuff.
Before ruling the idea out, do note that (apart form the fact that i HATE to use tables for designing and positioning stuff, but do not hesitate to use it for what it was meant to be) making tables will reduce the amount of code to be written. use css to size the cells and table. use inline to put background image. no js functions wat-so-ever.
please drop a comment if you disagree of if i am missing something :)

Categories

Resources