[英]Animate HTML5 canvas elements to change shape (on scroll or rollover) without gaps between them (the elements must be vertically connected)
How can I modify the shape of all elements (one by one) while scrolling on canvas or by rollover each element (to get random shape, but with some boundaries for the text to be in section more/less) and also to keep the elements vertically connected together? 我如何在画布上滚动或将每个元素翻转时修改所有元素的形状(一个一个地变)(以获取随机形状,但要使文本在部分中具有更多/更少的边界),并且还要保留这些元素垂直连接在一起? (no gaps in between to follow each other).
(彼此之间没有差距)。 I guess this can be done with coordinates?
我猜这可以用坐标来完成吗?
I've done some research and I haven't found a similar example. 我已经做了一些研究,但没有找到类似的例子。 I am open also to other solutions, javascript libraries, SCSS, skew() CSS function , clip-path CSS property , SVG or mask or anything else for the web (I mean, there is no special reason to use only one specific way).
我也对其他解决方案,JavaScript库,SCSS, skew()CSS函数 , 剪切路径CSS属性 ,SVG或mask或其他用于Web的网站持开放态度(我的意思是,没有特别的理由只使用一种特定的方式) 。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<style type="text/css">
#myCanvas {
border: 1px solid black;
width: 100%;
height: auto;
}
</style>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script>
$(function() {
var canvas = document.getElementById('myCanvas'),
width = window.innerWidth,
height = window.innerHeight,
elemWidth = window.innerWidth - 20,
lineheight = 30,
txt1 = 'Lorem 1 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
txt2 = 'Lorem 2 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
txt3 = 'Lorem 3 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
lines1 = txt1.split('\n'),
lines2 = txt2.split('\n'),
lines3 = txt3.split('\n');
window.addEventListener('resize', resizeCanvas, false);
function resizeCanvas() {
canvas.width = width;
canvas.height = height;
drawStuff();
}
resizeCanvas();
function drawStuff() {
// element 1
var poly1 = [5,100, (elemWidth-100),5, elemWidth,400, 5,300 ];
var ctx1 = canvas.getContext('2d');
ctx1.fillStyle = '#ff8080';
ctx1.beginPath();
ctx1.moveTo(poly1[0], poly1[1]);
for(item = 2 ; item < poly1.length - 1 ; item += 2) {
ctx1.lineTo(poly1[item], poly1[item + 1]);
}
ctx1.closePath();
ctx1.fill();
ctx1.fillStyle = "Black";
ctx1.font = '70px Arial';
ctx1.fillText("Some title 1",300,180);
ctx1.font = '30px Arial';
for (var i = 0; i<lines1.length; i++) {
ctx1.fillText(lines1[i], 300, 220 + (i*lineheight) );
}
// element 2
var poly2 = [5,300, elemWidth,400, (elemWidth-100),800, 50,600];
var ctx2 = canvas.getContext('2d');
ctx2.fillStyle = '#e9afaf';
ctx2.beginPath();
ctx2.moveTo(poly2[0], poly2[1]);
for(item = 2 ; item < poly2.length - 1 ; item += 2) {
ctx2.lineTo(poly2[item], poly2[item + 1]);
}
ctx2.closePath();
ctx2.fill();
ctx2.fillStyle = "Black";
ctx2.font = '70px Arial';
ctx2.fillText("Some title 2",300,480);
ctx2.font = '30px Arial';
for (var i = 0; i<lines2.length; i++) {
ctx2.fillText(lines2[i], 300, 520 + (i*lineheight) );
}
// element 3
var poly3 = [50,600, (elemWidth-100),800, elemWidth,940, 5,900];
var ctx3 = canvas.getContext('2d');
ctx3.fillStyle = '#c8b7b7';
ctx3.beginPath();
ctx3.moveTo(poly3[0], poly3[1]);
for(item = 2 ; item < poly3.length - 1 ; item += 2) {
ctx3.lineTo(poly3[item], poly3[item + 1]);
}
ctx3.closePath();
ctx3.fill();
ctx3.fillStyle = "Black";
ctx3.font = '70px Arial';
ctx3.fillText("Some title 3",300,780);
ctx3.font = '30px Arial';
for (var i = 0; i<lines3.length; i++) {
ctx3.fillText(lines3[i], 300, 820 + (i*lineheight) );
}
}
});
</script>
</body>
</html>
Update: I've created the suggested SVGs, since my target is the animation, any suggestions/ideas on updating those polygon points values (for example on rollover, I can use jquery) that the next polygons can follow (update points) dynamically and also staying connected? 更新:我创建了建议的SVG,因为我的目标是动画,所以有关更新这些多边形点值的任何建议/想法(例如,在翻转时,我可以使用jquery),下一个多边形可以动态跟随(更新点),还保持联系?
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<style type="text/css">
svg {
width: 100%;
height: auto;
}
</style>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
</head>
<body>
<svg width="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<polygon fill="#99bde5" points="0,5 95,0 100,35, 0,20" id="testElem"/>
<text x="10" y="12" text-anchor="left" fill="black" font-size="6">Some title 1</text>
<text x="10" y="15" text-anchor="left" fill="black" font-size="3">
<tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
<tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
</text>
<polygon fill="#c9e599" points="0,20 100,35 100,55, 5,50" id="testElem"/>
<text x="10" y="36" text-anchor="left" fill="black" font-size="6">Some title 1</text>
<text x="10" y="40" text-anchor="left" fill="black" font-size="3">
<tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
<tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
</text>
<polygon fill="#a5e599" points="5,50 100,55 94,75, 5,80" id="testElem"/>
<text x="10" y="63" text-anchor="left" fill="black" font-size="6">Some title 1</text>
<text x="10" y="67" text-anchor="left" fill="black" font-size="3">
<tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
<tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
</text>
<polygon fill="#99e5ca" points="5,80 94,74 100,100, 0,100" id="testElem"/>
<text x="10" y="89" text-anchor="left" fill="black" font-size="6">Some title 1</text>
<text x="10" y="92" text-anchor="left" fill="black" font-size="3">
<tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
<tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
</text>
</svg>
</body>
</html>
PS. PS。 The SVG points are x,y and clock-wise starting from top-left to bottom-left.
SVG点是x,y,从左上角到左下角是顺时针方向。
I think your best bet is going to be with an svg
. 我认为最好的选择是
svg
。 Here's an example of someone doing something pretty similar: https://codepen.io/erikdkennedy/pen/ygpwZg 这是某人做类似事情的示例: https : //codepen.io/erikdkennedy/pen/ygpwZg
The key is the points of the polygon
added within the svg
which creates a triangular section added to the rectangular header. 关键是在
svg
中添加的polygon
的点,该点创建添加到矩形标题的三角形截面。 The svg
here has no background so it's actually cutting a section out of the the header. 此处的
svg
没有背景,因此实际上是从标头中切出一部分。 This is basically removing a section from the parent element. 这基本上是从父元素中删除一个部分。 You can change it to
div
instead of header or whatever element you need it to be. 您可以将其更改为
div
而不是header或您需要的任何元素。
<polygon fill="white" points="0,100 100,0 100,100"/>
From the documentation , points
are pairs of (x,y) coordinates. 根据文档 ,
points
是(x,y)坐标对。 SVGs are very flexible and open to whatever customization you need. SVG非常灵活,可以根据需要进行任何自定义。 Setting up the points will be the only tricky part as you'll have to experiment till you get the shape(s) you need.
设置点将是唯一棘手的部分,因为您必须进行实验,直到获得所需的形状为止。 You'll need your parent elements to be large enough that you can cut sections out to fit your design.
您需要您的父元素足够大,以便可以切出适合您的设计的部分。
Update 更新
I haven't seen it confirmed in documentation, but the points appear to be percentages of the space provided. 我在文档中没有看到它的确认,但是要点似乎是所提供空间的百分比。 And, for some reason,
y
is flipped. 并且,由于某些原因,
y
被翻转。 So using that last example, 0,100 100,0 100,100
translates to bottom left, upper right, bottom right. 因此,使用最后一个示例,
0,100 100,0 100,100
转换为左下,右上,右下。
Update (animation) 更新(动画)
As far as animating your points, here's another helpful example on that. 至于使您的观点生气勃勃,这是另一个有用的例子 。 This boils down to creating an
animate
tag within the svg with an ID to reference, ( documentation here ). 这归结为在svg内创建一个带有参考ID的
animate
标签(请参见此处的文档 )。 You set your animation properties on the animate tag. 您可以在animate标签上设置动画属性。 To trigger it call the
id
of the reference and then trigger it with beginElement
: 要触发它,请调用引用的
id
,然后使用beginElement
触发它:
var animationToStar = document.getElementById("animation-to-star")
animationToStar.beginElement();
Note that the properties for to
on the animate
tag. 请注意,
animate
标签上的to
属性。 This dictates what the shape should be at the end of the animation. 这决定了动画结束时的形状。 For your use case you'll want to set up event listeners for
mouseover
, mouseleave
, and scroll
to fire off the animations per your design. 对于您的用例,您将需要为
mouseover
, mouseleave
设置事件监听器,并scroll
以根据设计触发动画。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.