Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【动效】:刮刮卡

【动效】:刮刮卡

作者头像
WEBJ2EE
发布于 2020-11-05 02:41:59
发布于 2020-11-05 02:41:59
1.3K00
代码可运行
举报
文章被收录于专栏:WebJ2EEWebJ2EE
运行总次数:0
代码可运行

1. 效果展示

2. 技术细节

2.1. Viewport

A viewport represents a polygonal (normally rectangular) area in computer graphics that is currently being viewed. In web browser terms, it refers to the part of the document you're viewing which is currently visible in its window (or the screen, if the document is being viewed in full screen mode). Content outside the viewport is not visible onscreen until scrolled into view.

  • Visual Viewport
    • The portion of the viewport that is currently visible is called the visual viewport. This can be smaller than the layout viewport, such as when the user has pinched-zoomed. The visual viewport is the visual portion of a screen excluding on-screen keyboards, areas outside of a pinch-zoom area, or any other on-screen artifact that doesn't scale with the dimensions of a page.
  • Layout viewport
    • The layout viewport is the viewport into which the browser draws a web page. Essentially, it represents what is available to be seen, while the visual viewport represents what is currently visible on the user's display device.

This becomes important, for example, on mobile devices, where a pinching gesture can usually be used to zoom in and out on a site's contents. The rendered document doesn't change in any way, so the layout viewport remains the same as the user adjusts the zoom level. Instead, the visual viewport is updated to indicate the area of the page that they can see.

2.2. Element.getBoundingClientRect()

The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.

  • The element's size is equal to its width/height + padding + border-width in the case that the standard box model is being used, or width/height only if box-sizing: border-box has been set on it.
  • The result is the smallest rectangle which contains the entire element, with read-only left, top, right, bottom, x, y, width, and height properties describing the overall border-box in pixels. Properties other than width and height are relative to the top-left of the viewport.

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <style type="text/css">
    html,
    body {
      width: 100%;
      height: 100%;
    }

    body {
      margin: 0;
    }

    .box {
      position: absolute;
      left: 300px;
      top: 300px;

      width: 400px;
      height: 200px;
      padding: 20px;
      margin: 100px auto;
      background: purple;
    }
</style>
</head>
<body>
<div class="box"></div>
<div class="result"></div>

<script type="text/javascript">
      let elem = document.querySelector('div.box');
      let rect = elem.getBoundingClientRect();

      const resultDiv = document.querySelector("div.result");
      resultDiv.innerHTML = "";

      for (var key in rect) {
        if(typeof rect[key] !== 'function') {
          let para = document.createElement('div');
          para.textContent  = `${ key } : ${ rect[key] }`;
          resultDiv.appendChild(para);
        }
      }
</script>
</body>
</html>

2.3. Touch

  • Touch Interface
    • The Touch interface represents a single contact point on a touch-sensitive device. The contact point is commonly a finger or stylus and the device may be a touchscreen or trackpad.
  • TouchEvent
    • The TouchEvent interface represents an UIEvent which is sent when the state of contacts with a touch-sensitive surface changes. This surface can be a touch screen or trackpad, for example. The event can describe one or more points of contact with the screen and includes support for detecting movement, addition and removal of contact points, and so forth.
    • Touches are represented by the Touch object; each touch is described by a position, size and shape, amount of pressure, and target element. Lists of touches are represented by TouchList objects.
  • touchmove event
    • Sent when the user moves a touch point along the surface. The event's target is the same element that received the touchstart event corresponding to the touch point, even if the touch point has moved outside that element.

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <style type="text/css">
    #wrapper{
      width: 600px;
      height: 600px;
      margin: 50px auto;
      border: 3px solid blue;
    }

    #viewer{
      position: fixed;
      top: 50%;
      transform: translate(0, -50%);
      border: 1px solid green;
    }
</style>
</head>
<body>
  <div id="wrapper">
  </div>

  <pre id="viewer">
  </pre>

  <script type="text/javascript">
    const ele = document.getElementById("wrapper");
    const viewer = document.getElementById("viewer");
    ele.addEventListener("touchmove", function(e) {
        e.preventDefault();
        var touch = e.targetTouches[0];
        if (touch) {
          viewer.innerHTML = `touchmove:
clientX:${touch.clientX}
clientY:${touch.clientY}`;
        }
    }, false);
</script>
</body>
</html>

2.4. Canvas

2.4.1. 填充图片

CanvasRenderingContext2D.drawImage():

  • The CanvasRenderingContext2D.drawImage() method of the Canvas 2D API provides different ways to draw an image onto the canvas

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <canvas id="canvas"></canvas>
  <script type="text/javascript">
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    const image = new Image(60, 45); // Using optional size for image

    image.onload = function(){ // Draw when image has loaded
      // Use the intrinsic size of image in CSS pixels for the canvas element
      canvas.width = this.naturalWidth;
      canvas.height = this.naturalHeight;

      // Will draw the image as 300x227, ignoring the custom size of 60x45
      // given in the constructor
      ctx.drawImage(this, 0, 0);

      // To use the custom size we'll have to specify the scale parameters 
      // using the element's width and height properties - lets draw one 
      // on top in the corner:
      ctx.drawImage(this, 0, 0, this.width, this.height);
    }; 

    // Load an image of intrinsic size 300x227 in CSS pixels
    image.src = 'https://media.prod.mdn.mozit.cloud/attachments/2013/06/22/5397/7a3ec0cae64a95ad454ac3bc2c71c004/rhino.jpg';
</script>
</body>
</html>

2.4.2. 填充文本

CanvasRenderingContext2D.fillText():

  • The CanvasRenderingContext2D method fillText(), part of the Canvas 2D API, draws a text string at the specified coordinates, filling the string's characters with the current fillStyle. An optional parameter allows specifying a maximum width for the rendered text, which the user agent will achieve by condensing the text or by using a lower font size.

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]);

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <canvas id="canvas" width="400" height="150"></canvas>
  <script type="text/javascript">
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    ctx.font = '50px serif';
    ctx.fillText('Hello world', 50, 60);
    ctx.fillText('Hello world', 50, 120, 140);
</script>
</body>
</html>

2.4.3. 绘制圆弧路径

CanvasRenderingContext2D.arc():

  • The CanvasRenderingContext2D.arc() method of the Canvas 2D API adds a circular arc to the current sub-path.

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
  • The rect() method creates a rectangular path whose starting point is at (x, y) and whose size is specified by width and height.

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <canvas id="canvas" width="400" height="150"></canvas>
  <script type="text/javascript">
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    ctx.rect(10, 20, 150, 100);
    ctx.stroke();
</script>
</body>
</html>

2.4.4. 合成操作

CanvasRenderingContext2D.globalCompositeOperation:

  • The CanvasRenderingContext2D.globalCompositeOperation property of the Canvas 2D API sets the type of compositing operation to apply when drawing new shapes.

语法:

3. 综合示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />  
  <style>
    .bg {
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      
      background-color: rgba(0, 0, 0, .2);

      display: flex;
      flex-direction: column;
        align-items: center;
        justify-content: center;
    }

    .scratch-card{
      width: 2.96rem;
      height: 3.45rem;

      background: url(./red-envelope.png) center center/contain no-repeat;

      position: relative;
    }

    .scratch-card > .scrape-area {
      width: 2.40rem;
      height: 1.20rem;

      position: absolute;
      bottom: 1rem;
      left: 50%;
      transform: translate(-50%, 0);
    }
    
    .scratch-card > .scrape-area > .award {}
    
    .scratch-card > .scrape-area > canvas {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
    }
    .scratch-card > .scrape-area > canvas.finish {
      display: none;
    }

    .scratch-card > .footer {
      position: absolute;
      left: 0;
      bottom: 0;
      
      width: 100%;
    }
</style>
</head>
<body>
  <div class="bg">
    <div class="scratch-card">
      <div class="scrape-area">
        <div class="award">
          <h1>奖品:旋风冲锋</h1>
        </div>
        <canvas id="scrape-canvas"></canvas>
      </div>
      <img class="footer" src="footer.png"/>
    </div>
  </div>
  <script type="text/javascript">
    !function(e, t) {
        var n = t.documentElement,d = e.devicePixelRatio || 1;
        function i() {
            var e = n.clientWidth / 3.75;
            n.style.fontSize = e + "px"
        }
        t.body.style.fontSize = "16px";
        i();
        e.addEventListener("resize", i);
        e.addEventListener("pageshow", function(e) {
              e.persisted && i()
        });
        2 <= d;
    } (window, document)
</script>


  <script>
    function initFestivalCanvas(){
      var remain = 100; // (次)

      const bridge = document.getElementById("scrape-canvas");
      const bridgeCanvas = bridge.getContext('2d');
      
      const img = new Image();
      img.onload = function(){  
        bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);

        bridgeCanvas.font = "36px bold 微软雅黑";
        bridgeCanvas.fillStyle = "red";
        bridgeCanvas.fillText("刮我一下", 75, 90);
      }
      img.src = './scrape-area-inner.png';

      function detectLeftButton(event) {
          if ('buttons' in event) {
              return event.buttons === 1;
          } else if ('which' in event) {
              return event.which === 1;
          } else {
              return event.button === 1;
          }
      }

      function getBrushPos(xRef, yRef) {
        var bridgeRect = bridge.getBoundingClientRect();
          return {
          x: xRef-bridgeRect.left,
          y: yRef-bridgeRect.top
          };
      }
            
      function drawDot(mouseX,mouseY){
        bridgeCanvas.beginPath();
          bridgeCanvas.arc(mouseX, mouseY, 15, 0, 2*Math.PI, true);
          bridgeCanvas.fillStyle = '#000';
          bridgeCanvas.globalCompositeOperation = "destination-out";
          bridgeCanvas.fill();
      }

      bridge.addEventListener("touchmove", function(e) {
          e.preventDefault();
          const touch = e.targetTouches[0];
          if (touch) {
            const brushPos = getBrushPos(touch.clientX, touch.clientY);
              drawDot(brushPos.x, brushPos.y);     
            if(remain-- < 0){
              const ele = document.getElementById("scrape-canvas");
              ele.className = ele.className + " " + "finish";
            }
          }
      }, false);
    }
    initFestivalCanvas();
</script>
</body>
</html>

参考:

Element.getBoundingClientRect(): https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect Viewport: https://developer.mozilla.org/en-US/docs/Glossary/Viewport https://developer.mozilla.org/en-US/docs/Glossary/visual_viewport https://developer.mozilla.org/en-US/docs/Glossary/Layout_viewport A tale of two viewports: https://www.quirksmode.org/mobile/viewports.html https://www.quirksmode.org/mobile/viewports2.html Touch: https://developer.mozilla.org/en-US/docs/Web/API/Touch https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent CanvasRenderingContext2D.arc() https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/arc globalCompositeOperation: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
从o1-mini到DeepSeek-R1,万字长文带你读懂推理模型的历史与技术
自 OpenAI 发布 o1-mini 模型以来,推理模型就一直是 AI 社区的热门话题,而春节前面世的开放式推理模型 DeepSeek-R1 更是让推理模型的热度达到了前所未有的高峰。
机器之心
2025/02/25
2330
从o1-mini到DeepSeek-R1,万字长文带你读懂推理模型的历史与技术
每周AI论文速递(250127-250131)
基准测试是追踪大语言模型(LLM)能力快速进展的重要工具。然而,这些基准测试在难度上并未跟上节奏:如今的 LLMs 在 MMLU 等流行基准测试上的准确率已超过 90%,这限制了对先进 LLM 能力的有根据测量。作为回应,我们介绍了“人类的最终考试”(HLE),这是一个多模式基准测试,在人类知识前沿设计,旨在成为同类中最后的封闭式学术基准测试,涵盖广泛的主题。 HLE 包含 3,000 个问题,跨越数十个学科,包括数学、人文学科和自然科学。HLE 由全球主题专家开发,包含适合自动化评分的多项选择题和简答题。每个问题都有一个已知的明确且易于验证的解决方案,但无法通过快速互联网检索获得答案。 先进的 LLMs 在 HLE 上表现出低准确性和校准度,突显了当前 LLM 能力与专家人类前沿之间的显著差距,在封闭式学术问题上的表现存在巨大差异。为了基于对模型能力的清晰理解来指导研究和政策制定,我们公开发布了 HLE,地址为https://lastexam.ai。
叶子的技术碎碎念
2025/04/08
600
每周AI论文速递(250127-250131)
深入了解Deepseek模型的最佳三篇论文
DeepSeek-R1:通过强化学习提升大型语言模型的推理能力。 2025年1月发布,提出了一种使用强化学习而非监督学习的方法,显著提升了语言模型在数学和逻辑推理任务中的表现,开辟了新的研究方向。
致Great
2025/02/09
1.5K0
深入了解Deepseek模型的最佳三篇论文
Sebastian Raschka:关于DeepSeek R1和推理模型,我有几点看法
著名 AI 研究者和博主 Sebastian Raschka 又更新博客了。这一次,他将立足于 DeepSeek 技术报告,介绍用于构建推理模型的四种主要方法,也就是如何通过推理能力来增强 LLM。Sebastian Raschka 表示:「我希望这能提供有价值的见解,并帮助你了解围绕这一主题的快速演变的文献和话题炒作。」
机器之心
2025/02/10
1810
Sebastian Raschka:关于DeepSeek R1和推理模型,我有几点看法
【AGI-Eval行业动态 NO.1】大模型行业太卷了,两周多了20+的模型
在白宫新闻发布会上,特朗普和 OpenAI CEO Sam Altman、软银 CEO 孙正义等人联合宣布了一个名为「星际之门」(Stargate Project)的人工智能项目。将开展 5000亿美元(6764亿新元)人工智能(AI)基础设施项目。
AGI-Eval评测社区
2025/02/20
1100
【AGI-Eval行业动态 NO.1】大模型行业太卷了,两周多了20+的模型
图解DeepSeek R1训练流程
这篇论文介绍了一种新的第一代推理模型——DeepSeek-R1系列,旨在通过强化学习(Reinforcement Learning, RL)提升大型语言模型(Large Language Models, LLMs)的推理能力。具体来说,论文试图解决以下几个问题:
致Great
2025/02/08
3310
图解DeepSeek R1训练流程
DeepSeek-R1:强化学习驱动的LLM推理能力提升
本文主要介绍一种新的训练策略,通过纯强化学习显著提升了LLM的推理能力,主要包括下面几点:
三掌柜
2025/02/06
3380
DeepSeek-R1:强化学习驱动的LLM推理能力提升
2024年人工智能年终总结报告|Artificial Analysis
临近年末,在人们都开始着手于年终总结的时候,Artificial Analysis也给出了关于2024年AI变革式发展的回顾。令人欣喜的是,我国的Qwen2.5 Instruct 72B与DeepSeek V2.5还有可灵AI等也名列其中。
新智元
2025/02/15
1690
2024年人工智能年终总结报告|Artificial Analysis
AI届的拼多多登临iOS榜,DeepSeek到底是什么来头?
DeepSeek的App目前已经登陆iOS免费榜前十,并超过了Google Gemini和微软的Copilot等同类竞品,可谓异军突起。
AntDream
2025/02/04
2640
AI届的拼多多登临iOS榜,DeepSeek到底是什么来头?
遇见DeepSeek之(1):初识
作者简介:刘世民,腾讯云TVP,公众号“世民谈云计算”作者,云计算技术专家,曾就职于华为、IBM、海航等公司,专注于云计算。曾在海航集团易航科技担任云服务事业群总经理一职,负责IDC、云平台、系统运维、信息安全以及用户服务等业务。维护有“世民谈云计算”技术博客和微信公众号。《OpenShift云原生架构原理与实践》作者之一、《Ceph Cookbook中文版》、《精通OpenStack》、《机器学习即服务:将Python机器学习创意快速转变为云端Web应用程序》译者之一
TVP官方团队
2025/02/05
2K0
遇见DeepSeek之(1):初识
AI日报 - 2025年04月16日
▎🤖 模型井喷 | OpenAI (o3/o4-mini, GPT-4.1), Meta (Llama 4 Scout/Maverick), Z.ai (GLM-4家族), Cohere (Embed 4), Google (DolphinGemma) 等发布新模型,多模态、长文本、高效推理成焦点。
訾博ZiBo
2025/04/15
2550
AI日报 - 2025年04月16日
AI日报 - 2024年05月12日
訾博ZiBo
2025/05/11
960
AI日报 - 2024年05月12日
DeepSeek R1 最新全面综述,近两个月的深度思考!
https://github.com/datawhalechina/hugging-llm/tree/main/resources
Datawhale
2025/02/20
9970
DeepSeek R1 最新全面综述,近两个月的深度思考!
揭秘DeepSeek R1-Zero训练方式,GRPO还有极简改进方案
DeepSeek-V3-Base 在强化学习(RL)调优之前就已经展现出「顿悟时刻」?RL 调整中不断增加的输出长度可能是由于 GRPO 中的 BIAS 造成的?
机器之心
2025/03/24
1020
揭秘DeepSeek R1-Zero训练方式,GRPO还有极简改进方案
每周AI论文速递(250210-250214)
我们研究了一种新型的语言模型架构,该架构能够通过在潜在空间中进行隐式推理来扩展测试时的计算。我们的模型通过迭代一个循环块,在测试时可以展开到任意深度。这与主流的推理模型不同,后者是通过生成更多 Token 来扩展计算能力的。与基于思维链的方法不同,我们不需要任何专门训练的数据,并能够使用小上下文窗口,还可以捕捉那些无法轻易用语言表示的推理类型。我们将一个概念验证模型调整到了 35 亿个参数和 800 亿个 Token 规模。结果表明,该模型在推理基准测试上可以提升性能,有时甚至显著增强,相当于增加了 50 亿个参数的计算负载。
叶子的技术碎碎念
2025/04/08
980
每周AI论文速递(250210-250214)
OpenAI最大秘密,竟被中国研究者破解?复旦等惊人揭秘o1路线图
推上多位网友表示,OpenAI o1和o3模型背后究竟是何原理——这一未解之谜,被中国研究者「发现」了!
新智元
2025/02/15
520
OpenAI最大秘密,竟被中国研究者破解?复旦等惊人揭秘o1路线图
小米7B大模型太能打了,高考数学139分!
长期跟踪关注统计学、机器学习算法、深度学习、人工智能、大模型技术与行业发展动态,日更精选技术文章。回复机器学习有惊喜资料。
Ai学习的老章
2025/06/17
730
小米7B大模型太能打了,高考数学139分!
Nature推荐:五大AI模型如何攻克不同科研场景?(内含Deepseek)
AI工具爆炸,模型遍地开花。今年的科研圈,要说最显眼的变化,绝对少不了“AI工具大跃进”。但问题来了!哪个模型,才是科研人该认真选择的外挂?
用户11203141
2025/03/12
2610
Nature推荐:五大AI模型如何攻克不同科研场景?(内含Deepseek)
【人工智能】你知道什么是DeepSeek吗?你有去了解过DeepSeek吗?新手要入门DeepSeek的必经之路——初识DeepSeek
2025年伊始,DeepSeek 在全球AI业界引发广泛关注,它以2048张H800 GPU,仅用两个月就训练出了一个媲美全球顶尖水平的模型,打破了大模型军备竞赛的既定逻辑。
蒙奇D索隆
2025/02/11
3790
【人工智能】你知道什么是DeepSeek吗?你有去了解过DeepSeek吗?新手要入门DeepSeek的必经之路——初识DeepSeek
大语言模型简史:从Transformer(2017)到DeepSeek-R1(2025)的进化之路
2025年初,中国推出了具有开创性且高性价比的「大型语言模型」(Large Language Model — LLM)DeepSeek-R1,引发了AI的巨大变革。本文回顾了LLM的发展历程,起点是2017年革命性的Transformer架构,该架构通过「自注意力机制」(Self-Attention)彻底重塑了自然语言处理。到2018年,BERT和GPT等模型崭露头角,显著提升了上下文理解和文本生成能力。2020年,拥有1750亿参数的GPT-3展示了卓越的「少样本」和「零样本」学习能力。然而,「幻觉」问题 — —即生成内容与事实不符,甚至出现「一本正经地胡说八道」的现象 — — 成为了一个关键挑战。2022年,OpenAI通过开发「对话式」的ChatGPT应对这一问题,采用了「监督微调」(SFT)和「基于人类反馈的强化学习」(RLHF)。到2023年,像GPT-4这样的「多模态模型」整合了文本、图像和音频处理能力,使LLM能够以更接近人类的「听」、「说」、「看」能力。近期推出的OpenAI-o1和DeepSeek-R1「推理模型」(Reasoning Model)在复杂问题解决方面取得突破,赋予LLM更接近人类「系统2思维」的深度推理能力,标志着人工智能在模拟人类思维模式上迈出了重要一步。此外,DeepSeek-R1模型以其「超成本效益」和「开源」设计挑战了AI领域的传统规范,推动了先进LLL的普及,并促进了各行业的创新。
致Great
2025/02/17
1.1K0
大语言模型简史:从Transformer(2017)到DeepSeek-R1(2025)的进化之路
推荐阅读
相关推荐
从o1-mini到DeepSeek-R1,万字长文带你读懂推理模型的历史与技术
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验