标签: javascript  python  js  java  css


In recent times, we have seen that the web is no longer a page in a browser full of squares. Every day there are more designs which incorporate irregular shapes.

最近,我们已经看到网络不再是充满正方形的浏览器中的页面。 每天都有越来越多的包含不规则形状的设计。

In this tutorial we want to teach you how to create and animate shapes with a jelly effect. At the end, you will be able to create the jelly shape you want, and animate it according to your needs without too much effort.

在本教程中,我们要教您如何创建具有果冻效果的形状和动画效果。 最后,您将能够创建所需的果冻形状,并根据需要对其进行动画处理,而无需付出过多的努力。

Specifically, in this first part we will see how to achieve the following result:


介绍 ( Introduction )

The maths behind an effect like this can be very difficult to achieve. That's why we have tried to group the code needed to create and animate jelly shapes in a library that is easy to use for developers.

这样的效果背后的数学很难实现。 这就是为什么我们试图将创建和动画果冻形状所需的代码分组到易于开发人员使用的库中。

At the same time, we have been inspired by this pen by Thom Chiovoloni, inspired as well in the game The Floor is Jelly. And we have started specifically from this implementation of the jelly physics.

同时,我们的灵感来自Thom Chiovoloni的这支钢笔 ,也受到《地板是果冻 》游戏启发。 而且,我们从果冻物理学的这种实现方式特别开始。

So, we've packaged this implementation into a library we've just called jelly.js, to which we've added everything we need to get jelly shapes easily. Then let's see how to use it!

因此,我们已将该实现打包到一个名为jelly.js的库中,并在其中添加了轻松获得果冻形状所需的所有内容。 然后,让我们看看如何使用它!

使用SVG路径创建形状 ( Creating the shapes with SVG paths )

We have chosen SVG paths to create the shapes, because we believe it is the easiest and most customizable way we have to do it. In this way, we can create the shapes that we want in a vector editor (like Inkscape or Illustrator), and insert them directly into our HTML document, or even import them from JavaScript.

我们选择了SVG路径来创建形状,因为我们认为这是我们最简单,最可定制的方法。 通过这种方式,我们可以在矢量编辑器(如Inkscape或Illustrator)中创建所需的形状,并将其直接插入HTML文档中,甚至从JavaScript导入它们。

For example, we can draw a simple shape like this:


Then we can include the relevant SVG code directly in the HTML:


<!-- SVG with a pentagon path -->
<!-- Note the `display: none` style, because we don't want to show the SVG, but just get the path from JavaScript -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="400" height="400" style="display: none">
    <path id="pentagon-path" d="m200 97.218 108.07 78.524-41.28 127.04h-133.58l-41.281-127.04z"/>

设置标记 ( Setup the markup )

We also need a canvas to draw the shape, and some other elements with the aim of moving a letter (S, from Scotch) coordinately with the centroid (average point) of the shape.


<div class="jelly-container">
    <!-- Canvas to draw the jelly pentagon -->
    <canvas class="jelly-canvas"></canvas>

    <!-- Text in the centroid of the jelly pentagon -->
    <div class="centroid-container">
        <div class="centroid-text">S</div>

有点风格 ( A bit of style )

For this example we need very few styles. Let's see the code:

对于此示例,我们需要很少的样式。 让我们看一下代码:

/* General styles */

html, body {
  margin: 0;

body {
  background-color: #D98327;
  overflow: hidden;

/* Jelly styles */

.jelly-container {
  position: relative;
  display: inline-block;
  left: 50%;
  margin-left: -200px;

.jelly-container, .jelly-canvas {
  width: 400px;
  height: 400px;

/* It's important to position the `.centroid-container` in the top-left corner
   This way the `.centroid-text` will be positioned in the center (with JavaScript) */
.centroid-container {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;

.centroid-text {
  font-size: 100px;
  color: white;

做成果冻 ( Making it jelly )

Finally we have arrived at the most fun part! Let's draw our pentagon on the canvas and see how we can animate it in a jelly way. But don't worry, it will be very easy using our library.

终于,我们到达了最有趣的部分! 让我们在canvas上绘制五边形,看看如何以果冻的方式对其进行动画处理。 但是不用担心,使用我们的库将非常容易。

We just need a few lines of code to draw our pentagon, and to get it reacting in a jelly way if we move the mouse to the edges of the shape:


/* Setup options */

var options = {
    paths: '#pentagon-path',     // Shape we want to draw
    pointsNumber: 10,            // Number of points
    maxDistance: 70,             // Max distance among points
    color: '#5C1523',
    centroid: '.centroid-text'   // Element to move accordingly with the centroid of the shape
    // debug: true               // Uncomment this to see the points

/* Initializing jelly */

var jelly = new Jelly('.jelly-canvas', options);

Note that the constructor of our library (Jelly) receives a canvas element and a set of options. We can also provide an array of options, a set of options for each shape we want to draw. For a detailed description of the available options, you can check the Github repository.

请注意,我们的库( Jelly )的构造函数会接收canvas元素和一组选项。 我们还可以提供一组选项,为我们要绘制的每种形状提供一组选项。 有关可用选项的详细说明,您可以检查Github存储库

We could leave it there, but our library has much more to offer. So let's look at some other things we can do.

我们可以把它留在那里,但是我们的图书馆有更多的选择。 因此,让我们看看我们可以做的其他事情。

实施果冻拖动 ( Implementing a jelly dragging )

To illustrate a little more the options we have (and for fun), let's see how we can shake our pentagon as we drag it across the screen.


First, we need to know when the mouse is inside the shape, to allow dragging it only when that happens. Check the following code, doing just that:

首先,我们需要知道鼠标何时位于形状内,以便仅在发生形状时才将其拖动。 检查下面的代码,这样做:

/* Check hover item (shape) and update cursor */

var container = document.querySelector('.jelly-container');
var hoverIndex = -1;

function checkHover() {
    // The `getHoverIndex` function will return the index of the shape being hovered, or -1
    hoverIndex = jelly.getHoverIndex();
    container.style.cursor = hoverIndex === -1 ? 'default' : 'pointer';

And let's see how we can implement a basic dragging logic. Please look at the comments to understand what is happening there, and pay special attention to the shake function:

让我们看看如何实现基本的拖动逻辑。 请查看注释以了解发生了什么,并特别注意shake功能:

/* Drag and drop */

var startX, startY, dx, dy, endX = 0, endY = 0, x = 0, y = 0, lastX = 0, lastY = 0;
var down = false;
// This will be the max distance for shaking
var shakeLimit = 5;

container.addEventListener('mousedown', function (e) {
    if (hoverIndex >= 0) {
        startX = e.clientX;
        startY = e.clientY;
        down = true;

document.addEventListener('mousemove', function (e) {
    if (down) {
        x = e.clientX - startX;
        y = e.clientY - startY;
        container.style.transform = 'translate(' + (endX + x) + 'px, ' + (endY + y) + 'px)';

        dx = x - lastX;
        dy = y - lastY;
        if (dx > shakeLimit || dx < - shakeLimit) dx = dx < 0 ? - shakeLimit : shakeLimit;
        if (dy > shakeLimit || dy < - shakeLimit) dy = dy < 0 ? - shakeLimit : shakeLimit;

        // The `shake` function will "move" the half of the points (alternately) the distance defined
        jelly.shake({x: - dx, y: - dy});

        lastX = x;
        lastY = y;

function mouseUp() {
    if (down) {
        down = false;
        endX += x;
        endY += y;

document.addEventListener('mouseup', mouseUp);

document.addEventListener('mouseout', function (e) {
    if (e.target.nodeName == 'HTML') {

性能和浏览器支持 ( Performance and browser support )

The browser support is really good, because all modern browsers have support for canvas. But jelly.js uses Promises, so we need a polyfill for any browser that does not support native promises.

浏览器支持确实很好,因为所有现代浏览器都支持canvas 。 但是jelly.js使用Promises,因此对于任何不支持本机jelly.js浏览器,我们都需要使用jelly.js

On the other hand, the performance is very variable according to the browsers and the operating systems. This is due to the CPU intensive work in each animation frame. So, don't abuse the use of these effects, because they can kill website performance.

另一方面,根据浏览器和操作系统的性能变化很大。 这是由于每个动画帧中的CPU密集型工作。 因此, 请勿滥用这些效果 ,因为它们可能会破坏网站性能。

结论 ( Conclusion )

And we are done! So far we have created a truly jelly pentagon without too much effort. Our shape also change the cursor on hover event, and respond to dragging in a jelly way as well :)

我们完成了! 到目前为止,我们无需付出太多努力就创建了一个真正的果冻五边形。 我们的形状还会在悬停事件上更改光标,并以果冻的方式响应拖动:)

You can see the final demo here, and you can get the full code on Github too.

您可以在此处查看最终的演示 ,也可以在Github上获取完整的代码

These are not the only things we can do. In fact, in the second part of this tutorial we will build an awesome slider, where everything will be jelly. In broad outline, we will learn how to:

这些不是我们唯一能做的。 实际上,在本教程的第二部分中,我们将构建一个很棒的滑块,其中的所有内容都会变得果冻。 概括地说,我们将学习如何:

  • Draw more jelly shapes, and text!

  • Use images inside the shapes, not only solid colors.

  • Animate the shapes to show or hide them smoothly.

  • Morph from a jelly shape to another.

  • Make the entire slider responsive.


We really hope you enjoyed it and found it useful! See you in the second part ;)

我们真的希望您喜欢它并发现它有用! 在第二部分见;)

翻译自: https://scotch.io/tutorials/drawing-and-animating-jelly-shapes-with-canvas


版权声明:本文为culiu9261原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。


spring cloud netflix (07) 服务的消费者(feign)

前言 完整知识点:spring cloud netflix 系列技术栈 Feign (同步通信 HTTP通信) feign是基于接口完成服务与服务之间的通信的 搭建Feign服务 项目结构 项目搭建 pom.xml application类 application.yml 使用feign完成服务与服务之间的通信 feign是基于接口完成服务与服务之间的通信的...

AtCoder Beginner Contest 174 E.Logs

AtCoder Beginner Contest 174 E.Logs 题目链接 到最后才发现是二分,菜菜的我/(ㄒoㄒ)/~~ 我们直接二分 [1,max{a[i]}][1,max\lbrace a[i]\rbrace][1,max{a[i]}] 即可,对每一个 midmidmid,每个数 a[i]a[i]a[i] 只需要切 a[i]−1mid\frac{a[i]-1}{mid}mi...


小程序开发工具与基础 小程序开发准备: 申请小程序账号( appid ) 下载并安装微信开发者工具 具体步骤如下: 先进入 微信公众平台 ,下拉页面,把鼠标悬浮在小程序图标上 然后点击 小程序开发文档 照着里面给的步骤,就可以申请到小程序账号了。 然后就可以下载 开发者工具 了 下载完打开后的界面就是这个样子 下面让我们来新建一个小程序开发项目: 在AppID输入自己刚刚注册的AppID就可以,或...

VMware centOS7 下通过minikube部署Kubernetes

1、环境准备: VMware CentOS-7-x86_64 CPU:2*2core 内存:8G 宿主机和虚拟机需网络互通,虚拟机外网访问正常 Centos发行版版本查看:cat /etc/centos-release root用户操作 2、禁用swap分区 Kubernetes 1.8开始要求关闭系统的Swap,可暂时关闭或永久禁用, 使用 $ free -m 确认swap是否为开启状态 $ s...


欢迎关注本人的微信公众号AI_Engine LogisticRegression 算法原理 一句话概括:逻辑回归假设数据服从伯努利分布,通过极大化似然函数(损失函数)的方法,运用梯度下降或其他优化算法来求解参数,来达到将数据二分类的目的。 定义:逻辑回归(Logistic Regression)是一种用于解决二分类(0 or 1)问题的机器学习方法,用于估计某种事物的可能性(不是概率)。比如某用户...



cocowy的编程之旅 在学习C语言的过程中我们经常可以看到或者听到这样一句话:数组其实等价于指针,例如: 在这里可以轻松的看出输出后他们的值相等,其实在计算机内存里面,p为本地变量,有着他自己的作用域。而指针变量q保存着这个数组的首地址,通过*号指向这个地址保存的变量值。 然而我们再看一个例子: 这个时候计算机报错,这是为什么呢? 其实原因很简单,指针说指向的这个字符串的地址是位于计算机代码段地...


广度搜索的基本使用方法 广度搜索不同于深度搜索,是一种一步一步进行的过程,每一个点只记录一遍。需要用到队列记录每一步可以走到的位置,找到目标位置输出步数即可。 用到的知识:结构体、队列 如图 首先我们需要定义一个结构体来存储每个遍历到的点和步数 广搜不会用到递归,所以可以直接在主函数里写,这里需要定义一个结构体队列 初始化队列并将起始点入列 遍历 完整代码...

NIO Socket 编程实现tcp通信入门(二)

1、NIO简介 NIO面向通道和缓冲区进行工作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。可以双向传输数据,是同步非阻塞式IO。NIO还引入了选择器机制,从而实现了一个选择器监听多个底层通道,减少了线程并发数。用NIO实现socket的Tcp通信需要掌握下面三个知识点: Buffer 缓冲区 Channel 通道 Selector 选择器   2、java.nio.Buff...

[字节码系列]ObjectWeb ASM构建Method Monitor

      在前面的篇章中,我们看到Java Instrutment的强大能力,本篇,我们将介绍如何使用ObjectWeb ASM的字节码增强能力构建Method Monitor       1.什么是ObjectWeb ASM      ObjectWeb ...

Core Location 电子围栏:入门

原文:Geofencing with Core Location: Getting Started 作者:Andy Pereira 译者:kmyhy 更新说明:Andy Pereira 将本教程升级至 Xcode 9.3 和 Swift 4.1。 Geofencing 会在设备进入/离开指定的电子围栏时通知应用程序。它可以让你写出一些很酷的应用程序,当你从家里出来时触发通知,或者在附近出现最爱的商...