I have two images locally. First image is a cup and another is a banner.
How do I warp and banner with the cup and then output a new file?
I've found the below function but how do I convert it to use in nodejs.
Wrap an image around a cylindrical object in HTML5 / JavaScript
function canvas3() {
var canvas = document.getElementById("canvas3");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/h_350/right_handle_cup_dsdhr7.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "http://res.cloudinary.com/pussyhunter/image/upload/v1488184107/500_F_97150423_M13q2FeAUZxxIx6CaPixHupprmyiVVli_skh6fe.jpg"
img.onload = function() {
var iw = img.width;
var ih = img.height;
//alert(iw)
var xOffset = 102, //left padding
yOffset = 110; //top padding
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (3 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 1.5, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
You can use canvas package in node.js too.
https://www.npmjs.com/package/canvas
import {loadImage, createCanvas } from "canvas";
...
router.get("/test", async (req: Request, res: Response) => {
const myImg = await loadImage('https://res.cloudinary.com/pussyhunter/image/upload/h_350/right_handle_cup_dsdhr7.jpg');
const canvas = createCanvas(400, 400);
const ctx = canvas.getContext("2d")
ctx.clearRect(0, 0, 500, 500)
const myImg2 = await loadImage('https://i.stack.imgur.com/NkKnV.png');
canvas.getContext("2d").drawImage(myImg,0,0,myImg.width, myImg.height);
// flat
// canvas.getContext("2d").drawImage(myImg2,myImg.width/2-30,myImg.height/2-30,60,60);
//rounded
draw(ctx, myImg2)
const buffer = canvas.toBuffer('image/jpeg');
// write a copy to the disk
//fs.writeFileSync("c:\\dev\\image.png", buffer);
res.write(buffer);
res.status(200);
res.end();
});
function draw(ctx, image) {
const iw = image.width;
const ih = image.height;
const xOffset = 102; //left padding
const yOffset = 110; //top padding
const a = 75.0; //image width
const b = 10; //round ness
const scaleFactor = iw / (4 * a);
// draw vertical slices
for (let X = 0; X < iw; X += 1) {
const y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(image, X * scaleFactor, 0, iw / 9, ih, X + xOffset, y + yOffset, 1, 174);
}
}
And the result;
Related
I have this code:
function CrossTemplate(gridOptions, canvas) {
const config = {color: '#000000', gridSize: 4, gridPadding: 0, strokeStyle: "#00000"};
const bw = canvas.width;
const bh = canvas.width;
const p = 0;
const cw = bw + p * 2 + 1;
const ch = bh + p * 2 + 1;
const context = canvas.getContext('2d');
canvas.height = ch;
canvas.width = cw;
if (!context) throw Error('Canvas context error');
for (var x = 0; x <= bw; x += config.gridSize) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 1; x <= bh; x += config.gridSize) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.strokeStyle = config.strokeStyle;
context.stroke();
return canvas;
}
https://jsfiddle.net/k2mg8dxs/12/
I wonder, why I dont see pattern canvas, where I did mistake?
I use parent context:
const context2 = canvas2.getContext('2d');
context2.fillStyle = context.createPattern(canvas, 'repeat');
I moved the creation of the pattern canvas inside the function that you defined and then return the canvas in the end. I think it makes it more transparent what happens. I have a hard time reading your code, but this seams to work.
And then you also missed the fillRect() in the end.
function CrossTemplate(gridOptions) {
let canvas = document.createElement('canvas');
canvas.width = 512;
canvas.height = 512;
const config = {
color: '#000000',
gridSize: 4,
gridPadding: 0,
strokeStyle: "#00000"
};
const bw = canvas.width;
const bh = canvas.width;
const p = 0;
const cw = bw + p * 2 + 1;
const ch = bh + p * 2 + 1;
const context = canvas.getContext('2d');
canvas.height = ch;
canvas.width = cw;
if (!context) throw Error('Canvas context error');
for (var x = 0; x <= bw; x += config.gridSize) {
context.moveTo(0.5 + x + p, p);
context.lineTo(0.5 + x + p, bh + p);
}
for (var x = 1; x <= bh; x += config.gridSize) {
context.moveTo(p, 0.5 + x + p);
context.lineTo(bw + p, 0.5 + x + p);
}
context.strokeStyle = config.strokeStyle;
context.stroke();
return canvas;
}
const canvas2 = document.getElementById('canvas2');
canvas2.width = 1024;
canvas2.height = 1024;
let canvas = CrossTemplate({
lineWidth: 1,
b: 24,
k: -1,
strokeStyle: '#215cff',
lineCap: 'square'
});
const context = canvas.getContext('2d');
const context2 = canvas2.getContext('2d');
context2.fillStyle = context.createPattern(canvas, 'repeat');
context2.fillRect(0, 0, canvas2.width, canvas2.height);
#canvas {
width: 512px;
height: 512px;
}
<canvas id="canvas2"></canvas>
I have a canvas where I use "fillText" with a string, saying for example "stackoverflow". Then I read the imagedata of the canvas in order to pick out each pixel of that text.
I want to pick the following from the pixel: x position, y position and its color. Then I would like to loop over that array with those pixels so I can draw back the text pixel by pixel so I have full control of each pixel, and can for example animate them.
However, I dont get it as smooth as I want. Look at my attach image, and you see the difference between the top text and then the text I've plotted out using fillRect for each pixel. Any help on how to make the new text look like the "fillText" text does?
Thanks
UPDATE: Added my code
var _particles = [];
var _canvas, _ctx, _width, _height;
(function(){
init();
})();
function init(){
setupParticles(getTextCanvasData());
}
function getTextCanvasData(){
// var w = 300, h = 150, ratio = 2;
_canvas = document.getElementById("textCanvas");
// _canvas.width = w * ratio;
// _canvas.height = h * ratio;
// _canvas.style.width = w + "px";
// _canvas.style.height = h + "px";
_ctx = _canvas.getContext("2d");
_ctx.fillStyle = "rgb(0, 154, 253)";
// _ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
var str = "stackoverflow";
_ctx.font = "32px EB Garamond";
_ctx.fillText(str,0,23);
_width = _canvas.width;
_height = _canvas.height;
var data32 = new Uint32Array(_ctx.getImageData(0, 0, _width, _height).data.buffer);
var positions = [];
for(i = 0; i < data32.length; i++) {
if (data32[i] & 0xffff0000) {
positions.push({
x: (i % _width),
y: ((i / _width)|0),
});
}
}
return positions;
}
function setupParticles(positions){
var i = positions.length;
var particles = [];
while(i--){
var p = new Particle();
p.init(positions[i]);
_particles.push(p);
drawParticle(p);
}
}
function drawParticle(particle){
var x = particle.x;
var y = particle.y;
_ctx.beginPath();
_ctx.fillRect(x, y, 1, 1);
_ctx.fillStyle = 'green';
}
function Particle(){
this.init = function(pos){
this.x = pos.x;
this.y = pos.y + 30;
this.x0 = this.x;
this.y0 = this.y;
this.xDelta = 0;
this.yDelta = 0;
}
}
Here is an update to your code that reuses the alpha component of each pixel. There will still be some detail lost because we do not keep the antialiasing of the pixels (which in effect alters the actual color printed), but for this example the alpha is enough.
var _particles = [];
var _canvas, _ctx, _width, _height;
(function(){
init();
})();
function init(){
setupParticles(getTextCanvasData());
}
function getTextCanvasData(){
// var w = 300, h = 150, ratio = 2;
_canvas = document.getElementById("textCanvas");
// _canvas.width = w * ratio;
// _canvas.height = h * ratio;
// _canvas.style.width = w + "px";
// _canvas.style.height = h + "px";
_ctx = _canvas.getContext("2d");
_ctx.imageSmoothingEnabled= false;
_ctx.fillStyle = "rgb(0, 154, 253)";
// _ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
var str = "stackoverflow";
_ctx.font = "32px EB Garamond";
_ctx.fillText(str,0,23);
_width = _canvas.width;
_height = _canvas.height;
var pixels = _ctx.getImageData(0, 0, _width, _height).data;
var data32 = new Uint32Array(pixels.buffer);
var positions = [];
for(i = 0; i < data32.length; i++) {
if (data32[i] & 0xffff0000) {
positions.push({
x: (i % _width),
y: ((i / _width)|0),
a: pixels[i*4 + 3] / 255
});
}
}
return positions;
}
function setupParticles(positions){
var i = positions.length;
var particles = [];
while(i--){
var p = new Particle();
p.init(positions[i]);
_particles.push(p);
drawParticle(p);
}
}
function drawParticle(particle){
var x = particle.x;
var y = particle.y;
_ctx.beginPath();
_ctx.fillStyle = `rgba(0,128,0,${particle.alpha})`;
_ctx.fillRect(x, y, 1, 1);
}
function Particle(){
this.init = function(pos){
this.x = pos.x;
this.y = pos.y + 30;
this.x0 = this.x;
this.y0 = this.y;
this.xDelta = 0;
this.yDelta = 0;
this.alpha = pos.a;
}
}
<canvas id="textCanvas"></canvas>
I'm drawing images on a canvas like this:
ctx.drawImage(data[i].image, data[i].pos.x, data[i].pos.y, data[i].pos.w, data[i].pos.h);
The picture is getting stretched and I don't want this. How can I simulate the CSS property?
background-size: cover
when drawing images on the canvas?
http://www.w3schools.com/cssref/playit.asp?filename=playcss_background-size&preval=cover
see the difference between 100% 100% (what I currently have) and cover (my goal).
It's a bit more complicated to get a cover functionality, though here is one solution for this:
Updated 2016-04-03 to address special cases. Also see #Yousef's comment below.
/**
* By Ken Fyrstenberg Nilsen
*
* drawImageProp(context, image [, x, y, width, height [,offsetX, offsetY]])
*
* If image and context are only arguments rectangle will equal canvas
*/
function drawImageProp(ctx, img, x, y, w, h, offsetX, offsetY) {
if (arguments.length === 2) {
x = y = 0;
w = ctx.canvas.width;
h = ctx.canvas.height;
}
// default offset is center
offsetX = typeof offsetX === "number" ? offsetX : 0.5;
offsetY = typeof offsetY === "number" ? offsetY : 0.5;
// keep bounds [0.0, 1.0]
if (offsetX < 0) offsetX = 0;
if (offsetY < 0) offsetY = 0;
if (offsetX > 1) offsetX = 1;
if (offsetY > 1) offsetY = 1;
var iw = img.width,
ih = img.height,
r = Math.min(w / iw, h / ih),
nw = iw * r, // new prop. width
nh = ih * r, // new prop. height
cx, cy, cw, ch, ar = 1;
// decide which gap to fill
if (nw < w) ar = w / nw;
if (Math.abs(ar - 1) < 1e-14 && nh < h) ar = h / nh; // updated
nw *= ar;
nh *= ar;
// calc source rectangle
cw = iw / (nw / w);
ch = ih / (nh / h);
cx = (iw - cw) * offsetX;
cy = (ih - ch) * offsetY;
// make sure source rectangle is valid
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
if (cw > iw) cw = iw;
if (ch > ih) ch = ih;
// fill image in dest. rectangle
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h);
}
Now you can call it like this:
drawImageProp(ctx, image, 0, 0, width, height);
and it will scale the image proportionally to fit inside in that container.
Use the two last parameters to offset the image:
var offsetX = 0.5; // center x
var offsetY = 0.5; // center y
drawImageProp(ctx, image, 0, 0, width, height, offsetX, offsetY);
If you're looking for a simpler solution that will work for most cases, and also includes css contain-like functionality, try this:
function fit(contains) {
return (parentWidth, parentHeight, childWidth, childHeight, scale = 1, offsetX = 0.5, offsetY = 0.5) => {
const childRatio = childWidth / childHeight
const parentRatio = parentWidth / parentHeight
let width = parentWidth * scale
let height = parentHeight * scale
if (contains ? (childRatio > parentRatio) : (childRatio < parentRatio)) {
height = width / childRatio
} else {
width = height * childRatio
}
return {
width,
height,
offsetX: (parentWidth - width) * offsetX,
offsetY: (parentHeight - height) * offsetY
}
}
}
export const contain = fit(true)
export const cover = fit(false)
slightly modified version of intrinsic-scale to include scale and offset
Usage:
import {cover, contain} from './intrinsic-scale'
const {
offsetX,
offsetY,
width,
height
} = cover(parentWidth, parentHeight, imageWidth, imageHeight)
// or...
const {
offsetX,
offsetY,
width,
height
} = contain(parentWidth, parentHeight, imageWidth, imageHeight)
ctx.drawImage(image, offsetX, offsetY, width, height)
Canvas image fitting canvas like background-size cover and contain
const coverImg = (img, type) => {
const imgRatio = img.height / img.width
const winRatio = window.innerHeight / window.innerWidth
if ((imgRatio < winRatio && type === 'contain') || (imgRatio > winRatio && type === 'cover')) {
const h = window.innerWidth * imgRatio
ctx.drawImage(img, 0, (window.innerHeight - h) / 2, window.innerWidth, h)
}
if ((imgRatio > winRatio && type === 'contain') || (imgRatio < winRatio && type === 'cover')) {
const w = window.innerWidth * winRatio / imgRatio
ctx.drawImage(img, (win.w - w) / 2, 0, w, window.innerHeight)
}
}
Codepen demo
Usage:
coverImg(myImage, 'cover');
coverImg(myImage, 'contain');
Try this (based on #daviestar's answer):
getCanvas = function(img, w, h) {
// Create canvas
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
// Set width and height
canvas.width = w;
canvas.height = h;
// Draw the image
let containerRatio = h / w;
let width = img.naturalWidth;
let height = img.naturalHeight;
let imgRatio = height / width;
if (imgRatio > containerRatio) { // image's height too big
height = width * containerRatio;
} else { // image's width too big
width = height / containerRatio;
}
let s = {
width: width,
height: height,
offsetX: (img.naturalWidth - width) * .5,
offsetY: (img.naturalHeight - height) * .5
};
ctx.drawImage(img, s.offsetX, s.offsetY, s.width, s.height, 0, 0, w, h);
return canvas;
}
The below script is a reference from #user1693593, and I do some modifications as below
use Destructuring assignment to make the options more flexible
The script provides a runnable example, so you don't worry the link is not found.
<script>
function clamp(num, a, b) {
return num > b ? b
: num < a ? a
: num
}
/**
* #param {CanvasRenderingContext2D} ctx
* #param {HTMLImageElement} img
* #param {Number} dx
* #param {Number} dy
* #param {Number} dw
* #param {Number} dh
* #param {Number} offsetX
* #param {Number} offsetY
* */
function drawImageProp(ctx, img, {dx = 0, dy = 0, dw = undefined, dh = undefined, offsetX = 0.5, offsetY = 0.5}) {
dw = dw ?? ctx.canvas.width
dh = dh ?? ctx.canvas.height
// keep bounds [0.0, 1.0]
offsetX = clamp(offsetX, 0, 1)
offsetY = clamp(offsetY, 0, 1)
let iw = img.width,
ih = img.height,
ratio = Math.min(dw / iw, dh / ih),
nw = iw * ratio,
nh = ih * ratio, // new prop. height
sx, sy, sw, sh, ar = 1;
// decide which gap to fill
if (nw < dw) ar = dw / nw
if (Math.abs(ar - 1) < 1e-14 && nh < dh) ar = dh / nh // updated
nw *= ar
nh *= ar
// source rectangle
sw = iw / (nw / dw)
sh = ih / (nh / dh)
sx = (iw - sw) * offsetX
sy = (ih - sh) * offsetY
// make sure source rectangle is valid
if (sx < 0) sx = 0
if (sy < 0) sy = 0
if (sw > iw) sw = iw
if (sh > ih) sh = ih
img.onload = (event) => {
// fill image in dest. rectangle
ctx.drawImage(event.target, sx, sy, sw, sh, dx, dy, dw, dh)
}
}
// Test Only 👇
window.onload = () => {
const testArray = [
["Default", (ctx, img)=>{drawImageProp(ctx, img, {})}],
["Full", (ctx, img)=>{drawImageProp(ctx, img, {offsetY:0})}], // If you don't want to it cutting from two sides, you can set "offsetY = 0" then it will cut a large part from the bottom
["1/2",(ctx, img)=>{drawImageProp(ctx, img, {dx:window.innerWidth/4, dy:window.innerHeight/4, dw: window.innerWidth/2, dh:window.innerHeight/2})}],
["3/4",(ctx, img)=>{drawImageProp(ctx, img, {dx:window.innerWidth/8, dy:window.innerHeight/8, dw: window.innerWidth*3/4, dh:window.innerHeight*3/4})}]
]
for (const [testName, drawFunc] of testArray) {
const btn = document.createElement("button")
btn.innerText = testName
btn.onclick = () => {
document.querySelectorAll(`canvas`).forEach(e=>e.remove()) // remove old data
const img = new Image(590, 470)
img.src = "https://upload.wikimedia.org/wikipedia/commons/b/bd/Test.svg"
const canvas = document.createElement("canvas")
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const ctx = canvas.getContext("2d")
drawFunc(ctx, img)
document.querySelector(`body`).append(canvas)
}
document.querySelector(`body`).append(btn)
}
}
</script>
For whom it may concern, I was looking for this answer but had to develop my own solution written in typescript, with file type solution:
const resizeBase64Img = (
base64: string, // image base64
type: string, // image mime type
newWidth: number, // new image width
newHeight: number // new image height
) =>
new Promise<string>((resolve, reject) => {
// rejects promise if no document variable
if (!document) {
reject('document is not available');
}
// create a brand new canvas element
const canvasElement = document.createElement('canvas');
// set its width
canvasElement.width = newWidth;
// and height
canvasElement.height = newHeight;
// adjust style for width
canvasElement.style.width = newWidth.toString() + 'px';
// and height
canvasElement.style.height = newHeight.toString() + 'px';
// get canvas context
const context = canvasElement.getContext('2d') as CanvasRenderingContext2D;
// create nem image
const img = new Image();
// set it's source from base64 argument
img.src = base64;
// when it loads
img.onload = () => {
// get the imgRatioType: landscape or portrait
const imgRatioType =
img.width / img.height >= 1 ? 'landscape' : 'portrait'; // 1 > landscape ; 1 < portrait
// if image is a portrait, then what's limiting it's sWidth is the img width. Otherwise it'll be the img height
const sWidth = imgRatioType === 'portrait' ? img.width : img.height;
// if image is a landscape, then what's limiting it's sHeight is the img height. Otherwise it'll be the img width
const sHeight = imgRatioType === 'landscape' ? img.height : img.width;
// if landscape, the image width is equals to 2 equal sx plus the sWidth. Otherwise, it should be 0.
const sx = imgRatioType === 'landscape' ? (img.width - sWidth) / 2 : 0;
// if portrait, the image height is equals to 2 equal sy plus the sHeight. Otherwise, it should be 0.
const sy = imgRatioType === 'portrait' ? (img.height - sHeight) / 2 : 0;
// destination canvas should have no space on dx
const dx = 0;
// neither on dy
const dy = 0;
// it's dWidth should be equal to the canvas width
const dWidth = canvasElement.width;
// and the same applies to dHeight with height
const dHeight = canvasElement.height;
// use clearRect for setting pixels in a clear rectangle with defined width and height
context.clearRect(0, 0, canvasElement.width, canvasElement.height);
// then draws the image
context.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
// resolve the promise with canvas toDataUrl method using type argument for mime
resolve(canvasElement.toDataURL(type));
};
img.onerror = (err) => {
// if image fails to load, rejects promise
reject(err);
};
});
I want to wrap image on cylindrical cup. I am using html5 and Java script for achieve this solution. I got some idea from this link: https://stackoverflow.com/questions/31424117/.
But i am not getting solution from this link.
I want to wrap remaining image behind the cup, Like mold the remaining part and add some button for rotation.
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function () {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height, 0, 0, iw, ih);
//start();
// outline
/*ctx.beginPath();
ctx.moveTo(88, 235.734375);
ctx.bezierCurveTo(88, 234.734375, 204, 298, 327, 234.734375);
ctx.stroke();*/
};
productImg.src = "https://d2z4fd79oscvvx.cloudfront.net/0018872_inspirational_teacher_mug.jpeg";
var img = new Image();
img.onload = start;
img.src = "http://blog.foreigners.cz/wp-content/uploads/2015/05/Make-new-friends.jpg";
var pointer = 0;
function start() {
var iw = img.width;
var ih = img.height;
//canvas.width = iw + 20;
//canvas.height = ih + 20;
var x1 = 125;
var y1 = 130;
var x2 = 180;
var y2 = 190;
var x3 = 405;
var y3 = 150;
// calc line equations slope & b (m,b)
var unitT = 1 / iw;
// draw vertical slices
for (var X = 0, t = 0; X < iw; X++, t += unitT) {
var xTop = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * x2 + t * t * x3;
var yTop = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * y2 + t * t * y3;
ctx.drawImage(img, X + pointer, 0, 1, ih, xTop, yTop, 0.85, ih - 600);
}
If i change the pointer value in above code, than remaining image
stretch.
var pointer = 100 ;
I want to wrap image on whole mug and rotate in left and right.
I've played around your plunkr for some time and came up with this:
http://plnkr.co/edit/83xAr99FjswWg0GHjDvJ?p=preview
function start() {
var iw = img.width;
var ih = img.height;
var xOffset = 125,
yOffset = 122;
var a = 122.0;
var b = 30.0;
var scaleFactor = iw / (2*a); //how many times original image is greater compared to our rendering area?
// draw vertical slices
for (var X = 0; X < iw; X+=1) {
var y = b/a * Math.sqrt(a*a - (X-a)*(X-a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, 6, ih, X + xOffset, y + yOffset, 1, ih - 605 + y/2);
}
}
I took this ellipsis equation http://www.mathopenref.com/coordgeneralellipse.html and turn it into the form where I can get Y-coordinate from related X-coordinate.
You can play with my plunkr even more to make the image more accurately cover the cup, but it is still far away from reality because this method is not considering different lightning features of the surface of the cup.
function canvas1() {
var canvas = document.getElementById("canvas1");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/c_scale,f_auto,h_350/left_handle_cup_i7ztfs.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
var xOffset = 102, //left padding
yOffset = 110; //top padding
//alert(ih)
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (4 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 9, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
function canvas2() {
var canvas = document.getElementById("canvas2");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
console.log("height");
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/h_350/canter_handle_cup_xyxhdd.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
// alert(iw)
var xOffset = 101, //left padding
yOffset = 110; //top padding
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (4 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 3, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
function canvas3() {
var canvas = document.getElementById("canvas3");
var ctx = canvas.getContext("2d");
var productImg = new Image();
productImg.onload = function() {
var iw = productImg.width;
var ih = productImg.height;
canvas.width = iw;
canvas.height = ih;
ctx.drawImage(productImg, 0, 0, productImg.width, productImg.height,
0, 0, iw, ih);
loadUpperIMage()
};
productImg.src = "http://res.cloudinary.com/pussyhunter/image/upload/h_350/right_handle_cup_dsdhr7.jpg"
function loadUpperIMage() {
var img = new Image();
img.src = "https://media1.giphy.com/media/j3uyvaaslUxNe/200_s.gif"
img.onload = function() {
var iw = img.width;
var ih = img.height;
//alert(iw)
var xOffset = 102, //left padding
yOffset = 110; //top padding
var a = 75.0; //image width
var b = 10; //round ness
var scaleFactor = iw / (3 * a);
// draw vertical slices
for (var X = 0; X < iw; X += 1) {
var y = b / a * Math.sqrt(a * a - (X - a) * (X - a)); // ellipsis equation
ctx.drawImage(img, X * scaleFactor, 0, iw / 1.5, ih, X + xOffset, y + yOffset, 1, 174);
}
};
}
};
setTimeout(function() {
canvas1()
}, 1000);
setTimeout(function() {
canvas2()
}, 2000);
setTimeout(function() {
canvas3()
}, 3000);
function updateItems(delta)
{
var $items = $('#group').children();
var $current = $items.filter('.current');
$current = $current.length ? $current : $items.first();
var index = $current.index() + delta;
// Range check the new index
index = (index < 0) ? 0 : ((index > $items.length) ? $items.length : index);
$current.removeClass('current');
$current = $items.eq(index).addClass('current');
// Hide/show the next/prev
$("#prev").toggle(!$current.is($items.first()));
$("#next").toggle(!$current.is($items.last()));
}
$("#next").click(function () {
updateItems(1);
});
$("#prev").click(function () {
updateItems(-1);
});
// Cause initial selection
updateItems(0);
#group div{
display: none;
}
#group div.current{
display: block;
}
#next, #prev{
width: 100px;
height 40px;
cursor:pointer;
color:red;
position:fixed;
}
#next{
float: right;
}
#prev{
float: left;
margin-left:40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<div id="next">next</div>
<div id="prev">prev</div>
<div id="group" >
<div>
<canvas id="canvas1"></canvas>
</div>
<div>
<canvas id="canvas2"></canvas>
</div>
<div>
<canvas id="canvas3"></canvas>
</div>
</div>
I made this (run snippet below)
var Canvas = document.getElementById('c');
var ctx = Canvas.getContext('2d');
var resize = function() {
Canvas.width = Canvas.clientWidth;
Canvas.height = Canvas.clientHeight;
};
window.addEventListener('resize', resize);
resize();
var elements = [];
var presets = {};
presets.shard = function (x, y, s, random, color) {
return {
x: x,
y: y,
draw: function(ctx, t) {
this.x += 0;
this.y += 0;
var posX = this.x + + Math.sin((50 + x + (t / 10)) / 100) * 5;
var posy = this.y + + Math.sin((55 + x + (t / 10)) / 100) * 7;
ctx.beginPath();
ctx.fillStyle = color;
ctx.moveTo(posX, posy);
ctx.lineTo(posX+random,posy+random);
ctx.lineTo(posX+random,posy+random);
ctx.lineTo(posX+0,posy+50);
ctx.closePath();
ctx.fill();
}
}
};
for(var x = 0; x < Canvas.width; x++) {
for(var y = 0; y < Canvas.height; y++) {
if(Math.round(Math.random() * 60000) == 1) {
var s = ((Math.random() * 5) + 1) / 10;
if(Math.round(Math.random()) == 1){
var random = Math.floor(Math.random() * 100) + 10;
var colorRanges = ['#8c8886', '#9c9995'];
var color = colorRanges[Math.floor(Math.random() * colorRanges.length)];
elements.push(presets.shard(x, y, s, random, color));
}
}
}
}
setInterval(function() {
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
var time = new Date().getTime();
for (var e in elements)
elements[e].draw(ctx, time);
}, 10);
<canvas id="c" width="1000" height="1000"\>
I just need to add one feature to be able to use it on the site I'm building it for. Some of the floating shards need to be blurred to give a sense of depth.
Can Canvas do this, and if so, how?
context.filter = 'blur(10px)';
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter
I used this few months ago, maybe it could work for you as well :
var canvas = document.getElementById("heroCanvas");
var canvasContext = canvas.getContext("2d");
var canvasBackground = new Image();
canvasBackground.src = "image.jpg";
var drawBlur = function() {
// Store the width and height of the canvas for below
var w = canvas.width;
var h = canvas.height;
// This draws the image we just loaded to our canvas
canvasContext.drawImage(canvasBackground, 0, 0, w, h);
// This blurs the contents of the entire canvas
stackBlurCanvasRGBA("heroCanvas", 0, 0, w, h, 100);
}
canvasBackground.onload = function() {
drawBlur();
}
Here the source : http://zurb.com/playground/image-blur-texture