Easiest way to make complex div with waves - html

I would like to create divs with complex waves, I'm coming across a lot of tutorials and I tried a lot of things but I can not do it. What is the best way to make waves and the background goes around and stops at the wave? What is the best/simplest way, I heard about the SVG but no skill with that. Is it complicated to realize? I wish I could draw curves and change the background accordingly as on this WordPress theme:
https://www.elegantthemes.com/blog/theme-releases/shape-dividers
I wish I could do that:
http://www.zupimages.net/viewer.php?id=19/22/jr0r.png
I have to learn SVG ? or use illustrator, too complicated directly in CSS if I have several waves. A software like an illustrator to do that for free with SVG exist?
and then do the rest of my style with bootstrap 4 etc? ...thank you

Normally you can do this using Perlin noise. However you can do it also by setting a number of points with successive x and random y on the svg canvas, and connecting the points with Béziers.
let w = 1000;
let h = 300;
svg.setAttributeNS(null,"viewBox",`0 0 ${w} ${h}`)
let n = 18; //number of points
let points = [];// the points array used to draw the curve
// add points to the points array
for(let x=0; x <= w; x+= w/n){
let y = h - Math.random()*h;
points.push({x:x,y:y})
}
// a function to connect all the points in the points array with beziers
function connect(points) {
let d = "";// the d attribute for the path
// move to the first point of the array
d+= `M${points[0].x}, ${points[0].y}`;
//build the path
for (var i = 1; i < points.length - 2; i++) {
var cp = {};
cp.x = (points[i].x + points[i + 1].x) / 2;
cp.y = (points[i].y + points[i + 1].y) / 2;
d+=`Q${points[i].x},${points[i].y} ${cp.x},${cp.y}`
}
//the last curve
let index = points.length-2
d+=`Q${points[index].x},${points[index].y} ${points[index + 1].x},${points[index + 1].y}`;
//close the path
d+=`V${h}H0z`
return d;
}
//set the attribute `d` for the wave
wave.setAttributeNS(null,"d",connect(points))
svg{border:1px solid}
<svg id="svg" >
<path id="wave" />
</svg>

I tried this before, just by using an image as border. You can create an image with a wavy border and play with transparency so you get the effect you need.

Related

How to detect that the AlphaMaskFilter is completely gone in easeljs/createjs

I am doing a little scratch/reveal game based on the AlphaMaskFilter example:
http://createjs.com/demos/easeljs/AlphaMaskReveal.html
I want to detect that the the mask is completely gone, or use a threshold (90% scratched for example).
I read the doc on AlphaMaskFilter, shape and graphics objects and im not really sure how to achieve this.
Im not even sure i Have acess to the pixel information and check the alpha channel to detect it, but even so, I wonder if I will performance issue.
any help is welcome, thanks.
**** EDIT **** ADD TO THE ACCEPTED ANSWER ****
So, I was able to have the pct of transparency using the AlphaMapFilter (thanks Lanny).
The AlphaMapFilter offer you a mapping to the alpha channel of all the pixels.
Here is a little sample code that worked for me:
// mShapeToScratch is a createjs Shape. like in the http://createjs.com/demos/easeljs/AlphaMaskReveal.html example
var alphaMaskFilter = new createjs.AlphaMapFilter(mShapeToScratch.cacheCanvas);
var canvas = alphaMaskFilter.alphaMap;
var ctx = canvas.getContext("2d");
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var alphaData = imgData.data;
var pixelTotal = rect.h*rect.w;
var transparentPixel = 0;
// rect.h is the height of the image and rect.w is the width not shown in the example
for (var y = 0; y < rect.h; ++y)
{
for (var x=0; x < rect.w; ++x)
{
var pixelIdx = (y*rect.w + x);
if(alphaData[pixelIdx] > 128) // transparent will be 255.
{
transparentPixel++;
}
}
console.log("transparent % = " + transparentPixel/pixelTotal);
This example checks all the pixels, but it's pretty easy to check one every X pixels to speeds up checks as Lanny suggested.
The alpha mask uses canvas composite operation, and not pixel access, so without some completely custom approach, there isn't a great way to do this.
Iterating pixels (check out AlphaMapFilter as an example) would work - but could be fairly slow. Maybe checking every 4th, 10th, or 25th pixel would speed it up.
Cheers.

Tricky Triangle Design implementation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am working on a website at the moment and have run into a problem with a triangle pattern.
The designer mocked the site up with triangular tiles and patterns :
Please note that I had to remove most of the content to post it here, but there is content on top of the triangular pattern.
I have done some research on how to implement the triangles in HTML,CSS and possibly JS(?) and came up with three possible options:
background-image
clipping divs and positioning them
using svg and positioning this
The problem with a background-image is that some of these tiles will later change on click and show things etc. So they really shouldn't be on a picture
I have started clipping and positioning divs, but this is just taking forever and I am starting to feel like this cannot be the best solution. Loads of fiddling and I think I will later have problems with inconsistencies
I don't have much experience working with svg, but I would have to draw them all one by one and position them as well (right? this is an assumption). Doesn't seem like the best practice approach.
Does anyone have any input on how I could solve this or do I just have to follow through with one of the solutions named above, as there is no quicker way.
I would really appreciate any ideas.
Thanks Anton
If you decide to go with the SVG route then the code to create the triangles can be relatively small. Store the colors in an array of arrays. Store the horizontal and vertical distance between triangles in two variables (e.g. dx and dy). Then loop through the colors array to draw the individual triangles.
JavaScript code...
var svgNS = "http://www.w3.org/2000/svg";
function drawTriangles() {
var svg = document.getElementById("mySvg");
var colors = [
["#0000FF", "#0044FF", "#0088FF", "#00CCFF"],
["#4400FF", "#4444FF", "#4488FF", "#44CCFF"],
["#8800FF", "#8844FF", "#8888FF", "#88CCFF"],
["#CC00FF", "#CC44FF", "#CC88FF", "#CCCCFF"],
];
var n = colors.length;
var m = colors[0].length;
var dx = 100;
var dy = 75;
for (var i = 0; i < n; i++) {
for (var j = 0; j < m; j++) {
var polygon = document.createElementNS(svgNS, "polygon");
var point0 = svg.createSVGPoint();
var point1 = svg.createSVGPoint();
var point2 = svg.createSVGPoint();
if ((i + j) % 2 === 0) {
point0.x = j * dx;
point0.y = i * dy;
point1.x = (j + 1) * dx;
point1.y = (i + 1) * dy;
point2.x = (j + 1) * dx;
point2.y = (i - 1) * dy;
} else {
point0.x = (j + 1) * dx;
point0.y = i * dy;
point1.x = j * dx;
point1.y = (i - 1) * dy;
point2.x = j * dx;
point2.y = (i + 1) * dy;
}
polygon.setAttribute("fill", colors[i][j]);
polygon.points.appendItem(point0);
polygon.points.appendItem(point1);
polygon.points.appendItem(point2);
svg.appendChild(polygon);
}
}
}
drawTriangles();
<svg id="mySvg" width="400" height="225"></svg>
If css shapes are an option, i would recommend to use them.
https://css-tricks.com/examples/ShapesOfCSS/
However you chose to create the boundaries of your containers, if you embed the svg directly into the html, you can access all the elements the same way you access html elements, and with them you can get their vertices. This way you could use that information to create the shapes.
The downside of that approach is that it is highly depending on javascript, if it is disabled or fails, the complete layout will fail, too. But you can react on layout changes at runtime.
To overcome this you might be able to process the svg on the server, but there you are missing out the final dimensions, what might not be problem if you use percentage values to position your content containers, but a huzzle to code.
All in all, if got this right, creating such a layout where content is arranged in triangles will need a lot of code in each case.
If the page will stay small and not much content be assigned, than doing everything by hand might be faster.

how to move polygon points depending on movement of one point?

i have polygon say (Hexagonal with 6 lines) this Hexagonal connected from center with 6 point That make 6 triangles
I need when move any point(cause to move triangles) ,, other points move like this point i mean if the left point move to lift other points move to the left and so on
the code I want like this ptcP1.x and ptcP1.y the point that i moving it other point move depend on ptcP1 movement note that, this equations work fine in square shape ,, put in Penta and hexa ..etc this equations in valid so can any one help me
function button1_triggeredHandler( event:Event ):void
{
mode="mode2";
//trace(list.selectedIndex);
if(list.selectedIndex==1)
{
DrawSqure.ptcP1.x = Math.random() + 50;
DrawSqure.ptcP1.y = Math.random() + 50;
DrawSqure.ptcP2.y = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP2.x = DrawSqure.ptcP1.y;
DrawSqure.ptcP3.x = 50-DrawSqure.ptcP1.y;
DrawSqure.ptcP3.y = DrawSqure.ptcP1.x;
DrawSqure.ptcP4.x = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP4.y = 50-DrawSqure.ptcP1.y;
}
As stated in the comments, storing the vertices/points into a container (Array or Vector) and then adjusting those positions when you move is the best way to do it. Here is an example of how that might work:
//setup array or vector of vertices
var polygonVertices:Array = [DrawPolygon.ptcP1, DrawPolygon.ptcP2, DrawPolygon.ptcP3, DrawPolygon.ptcP4];
This method will take all the vertices and apply the translation:
//function for adjusting all the vertices based on the distance you pass
function moveShape( vertices:Array, dx:Number, dy:Number ) {
var i:int;
for ( ; i < vertices.length; i++ ) {
vertices[i].x += dx;
vertices[i].y += dy;
}
}
Then you would just need to know your distance X & Y your shape has moved and you can call moveShape( polygonVertices, 100, 100 );
I inserted 100,100 as the distance parameters as an example, but this should give you the results you are looking for.

HTML5: Inverse text-color on canvas

I want to draw text on a canvas in the inverse color of the background (to make sure the text is readible no matter the background color). I believe in oldskool bitblt-ing, this was an XOR operation.
How to do this?
Update: most of the newer browsers now support the blending mode "difference" which can achieve the same result.
context.globalCompositeOperation = "difference";
Updated demo.
Old answer:
One should think that the XOR mode for composition would do this, but unfortunately canvas' XOR only XORs the alpha bits.
By applying the following code we can however receive a result such as this:
You can make an extension to the canvas like this:
CanvasRenderingContext2D.prototype.fillInversedText =
function(txt, x, y) {
//code - see below
}
Now you can call it on the context as the normal fillText, but with a slight change:
ctx.fillInversedText(txt, x, y);
For this to work we do the following first - measure text. Currently we can only calculate width of text and then assume the height. This may or may not work well as fonts can be very tall and so forth. Luckily this will change in the future, but for now:
var tw = this.measureText(txt).width;
var th = parseInt(ctx.font, '10');
th = (th === 0) ? 10 : th; //assume default if no font and size is set
Next thing we need to do is to setup an off-screen canvas to draw the text we want ot invert:
var co = document.createElement('canvas');
co.width = tw;
co.height = th;
Then draw the actual text. Color does not matter as we are only interested in the alpha channel for this canvas:
var octx = co.getContext('2d');
octx.font = this.font;
octx.textBaseline = 'top';
octx.fillText(txt, 0, 0);
Then we extract the pixel buffers for the area we want to draw the inverted text as well as all the pixels for the off-screen canvas which now contains our text:
var ddata = this.getImageData(x, y, tw, th);
var sdata = octx.getImageData(0, 0, tw, th);
var dd = ddata.data; //cache for increased speed
var ds = sdata.data;
var len = ds.length;
And then we invert each pixel where alpha channel for pixel is greater than 0.
for (var i = 0; i < len; i += 4) {
if (ds[i + 3] > 0) {
dd[i] = 255 - dd[i];
dd[i + 1] = 255 - dd[i + 1];
dd[i + 2] = 255 - dd[i + 2];
}
}
Finally put back the inverted image:
this.putImageData(ddata, x, y);
This may seem as a lot of operations, but it goes pretty fast.
Demo (warning if you are sensitive to flicker)
(the psychedelic background is just to have some variations as fiddle needs external images and most are prevented by CORS when we use pixel manipulation).
I've removed my old answer, as it did not solve the question. As of recently, there are new globalCompositeOperations that do all kinds of great things. I've created an example that shows how to obtain inverted text. In case that link breaks, the method is essentially this:
ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white";
//draw inverted things here
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

Hit testing pseudo 3d space

So I am writing a little mini pseudo 3d engine for the canvas element in html5. In the code below I am drawing a bunch of squares with varying positions and rotations (rotation around the z axis, so no deformation)
Now I want to be able to tell which square the user clicks on. In the objects array the items are supported by the z position starting with the squares the furthest away from the camera (so that they draw properly). So given a 3d point relative to the top left of the corner of the canvas how can I tell which square was clicked?
//Draw objects
for (var i = 0; i < objects.length; i++) {
var object = objects[i];
var cz = object.position.z - camera.position.z;
if (cz > 0) {
cz = 1 / ((cz - 1) * 0.75 + 1);
context.save();
context.translate(halfWidth, halfHeight); //viewport transform
context.scale(1, -1); //invert y axis
context.scale(cz, cz); //perspective
context.translate(-camera.position.x, -camera.position.y); //camera transform
context.translate(object.position.x, object.position.y); //world transform
context.rotate(object.rotation);
context.fillStyle = object.color;
context.fillRect(-40, -40, 80, 80);
context.restore();
}
}
P.S. If I am doing anything weird or backwards and you know of a way to improve, I would love to hear suggestions
I would suggest that you draw the objects with the same transformations to a hidden canvas of the same size, but give each square a unique color (maybe derived from the index i).
You would do that like this:
var col = index.toString(16); // convert to hex
while (col.length < 6) col = "0"+col; // pad leading 0s
ctx.fillStyle = "#"+col;
ctx.fillRect(-40,-40,80,80);
Then when you get a mouseclick event on the visible canvas, look at that location in your hidden one to get the color (index) of the selected object:
var colData = ctx.getImageData(clickX, clickY, 1, 1).data;
var index = (colData[2]<<16) | (colData[1]<<8) | colData[0];
This will work for up to 16M objects and is fairly simple.