精华内容
下载资源
问答
  • 用于Web前端实现屏幕截图功能,非常好用
  • html2canvas 是一款js屏幕截图插件。该插件可以将当前屏幕的DOM元素按原样进行截图,通过canvas生成图片。
  • JS屏幕截图

    千次阅读 2018-11-30 02:10:35
    title: JS屏幕截图 date: 2018-07-09 10:56:58 tags: 前端 categories: 前端 最近比较忙,很久没写博客了,今天抽空将最近项目中遇到的一些问题及一些解决方案记录一下。 最近接触的项目主要是移动端的,关于...

    title: JS屏幕截图 date: 2018-07-09 10:56:58 tags:

    • 前端 categories:
    • 前端

    最近比较忙,很久没写博客了,今天抽空将最近项目中遇到的一些问题及一些解决方案记录一下。

    最近接触的项目主要是移动端的,关于移动端方面适配之类的文章太多了,对这方面的技术不做过多的阐述。主要记录下这次中遇到的一些吧。

    1. 截图分享功能
    2. 按钮防重复点击(节流函数应用)
    3. 下拉刷新,上拉加载更多(这个地方有坑)
    4. 性能优化方面

    截图分享功能

    事因:移动端分享功能,产品经理给的原型是 点击分享后将需要分享的内容放在一个固定的容器中,生成UI指定的样式后,通过图片的方式分享到微信、微博等第三方应用中。

    技术选型:最初想到的是用 html2canvas,嗯,说完就去写了一个demo,具体效果也还可以,就是这个不能引用跨域的图片,解决的办法是直接先请求下来图片,再直接给准成Base64放上去了,简单粗暴。。。

    不过最后还是放弃了使用html2canvas,原因是在github的issues里说道这个插件可能还是会有些问题,比如导致生成的图片模糊(这个github也有专门针对解决的方案),页面空白之类的。又查了下发现一个stars数较高的,就是今天想说的了 rasterizeHTML.js,经过在项目检验,这个确实挺好用的,用法在github上挺详细的,点击前面的链接就OK啦~~~

    需要注意的地方:

    1. 生成图片是需要先生成canvas的,而canvas是需要指定宽高的。所以在生成图片也是需要宽高的,移动端宽度采用 750比较合适,高度的话可以写上最小高度 1350,这样保证截的图片长宽比比较合适,具体高度的话,除去UI给图的头尾部分固定高度,内容方面根据每行的高度来判断,写点计算代码算下 所需内容能生成多少行文字,再想加一下就好了。

    2. 比较关键的地方是此项目采用的是安卓套webview的方式完成,所以当点击分享的时候,需要传给安卓的是一张图片地址,而 第一步生成的是canvas,我们需要将其转换成blob,再通过formdat的方式将图片上传到后端,拿到图片链接,最后才是将图片传给安卓并分享出去。贴下关键代码:

    截图模板.js

    import {codeHtml} from "../../common/share-html";
    export default function (data = {}) {
        const {
            shareImage,
            shareTitle,
            shareTime,
            shareContent,
            contentHeight,
            shareCode,
            shareMsg
        } = data;
        const w = document.getElementsByTagName('html')[0].style.fontSize;
        return `
    <div style="width: 750px;text-align: center;background-color: #ffffff;">
    <style type="text/css">
    html {
    font-size: 100px;
    height: 100%;
    }
    body{
    padding: 0;
    margin: 0;
    background-color: #ffffff;
    height: 100%;
    }
    
    p {
        margin: 0;
        padding: 0;
    }
    
    .modal-img {
        width: 100%;
    }
    .modal-content {
        font-size: .28rem;
        background: #fff;
        height: 100%;
        /*padding-bottom: 60px;*/
    }
    .model-title {
      font-size: .36rem;
      font-weight: bold;
      padding-top: .15rem;
    }
    
    .modal-time {
       color: #9B9B9B;
       font-size: .24rem;
       padding-top: .15rem;
       text-align: left;
       padding-left: .5rem;
    }
    .model-main-content {
          /*text-indent: 2em;*/
          margin-top: .12rem;
          padding: 0 .5rem;
          font-size: .3rem;
          line-height: 1.5;
          min-height: ${contentHeight}px;
          text-align: justify;
          color: #191919;
        }
    
    ${codeHtml.style}
    
    </style>
         <div class="modal-content">
                    <img class="modal-img" src="/static/img/header.png"/>
                    <div class="model-title">${shareTitle}</div>
    
                    <div class="modal-time">${shareTime}</div>
                    <div class="model-main-content">
                        ${shareContent}
    
                    </div>
                    ${codeHtml.html}
    
        </div>
    
    </div>
    
        `;
    }
    复制代码

    分享页面.js

    ****
    import marketShareHtml from "../../../components/share-template/share-img";
    ****
    
     async handleShare(news) {let shareTemContent = this.htmlFilter(news.content);
                let shareTemTime = dayjs(news.publishTime * 1000).format('YYYY-MM-DD HH:mm');
                const tempImg = new Image();
                const vm = this;
                // console.log(shareTemContent.length / 20, 'length');// 自动计算内容高度,自适应canvas高度。
                const templateHeight = shareTemContent.length / 20 * 40;
                const tempH = templateHeight > 580 ? templateHeight : 580;
                tempImg.src = '/static/img/header.png';
                // 图片加载完成后生成 html模板
                tempImg.onload = async function () {
                    const html = marketShareHtml({
                        shareTitle: '',
                        shareTime: shareTemTime,
                        shareContent: shareTemContent,
                        contentHeight: tempH,
                        shareCode: '',
                        shareMsg: ''
                    });
                    // console.log(html, 22222);
                    const canvas = document.createElement('canvas');
                    let tempHeight = 720;
                    const finalHeight = tempHeight + tempH;
                    // console.log(finalHeight, 'finalHeight');
                    canvas.width = 750;
                    canvas.height = finalHeight > 1280 ? finalHeight : 1280;
                    // console.log(canvas.height, 'canvas.height');
                    const res = await
                    // 这个地方是关键代码---绘制canvas
                    vm.$rasterizeHTML.drawHTML(html, canvas);
                    // 这个地方是生成blob,
                    vm.shareImage = canvas.toBlob((blob) => {
                        // var newImg = document.createElement("img"),
                        // console.log('blob', blob);
                        const url = window.URL.createObjectURL(blob);
    
    
                        if (vm.first) {
                            vm.handleShare(news);
                            vm.first = false;
                        } else {
                            vm.$store.dispatch('dynamic/newsFlash/changeBlob', blob);
    
                            // 下面是将blob变成图片地址的实现方法。
                            // const fd = new FormData();
                            // fd.append('img', blob, 'image.png');
                            // axios({
                            //     url: '/b/a/u/info/img',
                            //     method: 'post',
                            //     data: fd,
                            //     headers: {'Content-Type': 'multipart/form-data'}
                            // }).then(function (data) {
                            //     console.log(data);
                            // }).catch(function (err) {
                            //     console.log(err);
                            // });
                            vm.$store.dispatch('dynamic/common/toggleSharePopupModal', {title: '分享后需返回APP才能获得奖励', showModal: true, screenShot: null, image: vm.shareImage});
                            // vm.$ModalHelper.afterOpen('flash-news-wrap');
                        }
                    });
                };
            },
    
    
    复制代码

    屏幕截图这块差不多就完结了,主要就是几种格式之间的转化,多注意下就好了。

    展开全文
  • 本文详细解读了Dcloud的H5+API中webview draw使用方法,并给出draw截图的Android,iOS通用方法,希望对大家有所帮助
  • 通过video标签和canvas实现视频截图录制功能 只支持同域名资源录制,不支持录制来自其它网站的媒体源
  • js屏幕截图

    2020-08-06 16:43:49
    版权所有:*******        技术支持:中化信息技术有限公司 ...el-dialog title="纠错" :visible.sync="dialogVisible" width="50%">...img :src="dataURL" alt...
    版权所有:*******        技术支持:中化信息技术有限公司
    <!--  快捷键弹出框  -->
    <el-dialog title="纠错" :visible.sync="dialogVisible" width="50%">
      <img :src="dataURL" alt="" style="height:100%;width:100%">
      <el-form ref="findProblem" :model="findProblem" label-width="auto" style="padding-top: 20px;">
        <el-form-item label="问题描述:" prop="problemInfo" :rules="[{ required: true, message: '问题描述不能为空',trigger: 'blur'},]">
          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入内容" v-model="findProblem.problemInfo">
          </el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
    	    <el-button type="primary" :disabled="isDisabledTJ" @click="submitForm('findProblem')">提 交</el-button>
    
    	  </span>
    </el-dialog>
    
    展开全文
  • node.js实现快速截图

    2020-10-21 15:52:07
    本文给大家汇总介绍了几种node.js实现快速截屏的方法,这里分享给大家,希望大家能够喜欢。
  • 比较:将新的屏幕截图与收集的屏幕截图进行比较 安装 npm install --save-dev @cznec/screenshot-compare or yarn add -D @cznec/screenshot-compare 用法 创建收集文件collection.js const Screenshot = require ...
  • JS实现截屏

    热门讨论 2012-11-25 20:51:36
    用的是百度的JS版API,由于百度API未提供截屏功能,便自己动手写,用网页调用APPLET方式实现。附代码,提供JSP和HTML两个版本。亲测可用,觉得有用的请顶! PS: 1、保证D盘有个img目录或者自己修改代码自动创建...
  • h5实现屏幕截图功能

    2020-09-18 17:36:59
    js实现屏幕截图功能,可以根据需要移动选区,缩放选区,最大可截的宽高是widows.width和windows.height
  • 梅青格 受 Cezanne 和 Sheut 启发的 node.js 屏幕截图测试库。 ##去做 自述文件 入门 在此处有一些适当的文档之前,开始使用 Metzinger 的最佳方法是查看 spec/demoSpec.js
  • Arcgis for js 4.5 仿qq截图,指定地图范围的地图截屏截图结果将以图片路径形式返回。
  • 通过 JavaScript 从网络摄像头捕获屏幕截图 特征 js-webcam-screenshot 可以直接从浏览器中捕获屏幕截图。 然后可以将图像呈现在和/或可以作为普通文件上传发布。 js-webcam-screenshot 可以使用来自各种框架...
  • JS 实现网页截屏五种方法

    千次阅读 2020-12-14 08:00:00
    作者:lucknesshttps://segmentfault.com/a/1190000037673677最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,...

    作者:luckness

    https://segmentfault.com/a/1190000037673677

    最近研究了下如何利用JavaScript实现网页截屏,包括在浏览器运行的JS,以及在后台运行的nodeJs的方法。主要看了以下几个:

    1. PhantomJS

    2. Puppeteer(chrome headless)

    3. SlimerJS

    4. dom-to-image

    5. html2canvas

    测试的网页使用了WebGL技术,所以下面的总结会和WebGL相关。

    名词定义

    headless browser

    无界面浏览器,多用于网页自动化测试、网页截屏、网页的网络监控等。

    PhantomJS

    PhantomJS是可以通过JS进行编程的headless浏览器,使用的是QtWebKit内核。

    实现截屏的代码,假设文件名为github.js:

    // 创建一个网页实例
    var page = require('webpage').create();
    // 加载页面
    page.open('http://github.com/', function () {
        // 给网页截屏,保存到github.png文件中
        page.render('github.png');
        phantom.exit();
    })
    

    运行:

    phantomjs github.js
    

    普通的页面没有问题,但是如果运行包含WebGL的页面,发现截屏不对。经过一些调查,发现不支持WebGL,github issue。

    总结:

    1. PhantomJs已经停止维护了,所以不太建议继续使用。停止维护的一个原因是chrome发布的headless版本对它造成了一定冲击。

    2. 不支持WebGL。但是,还是有开发者说可以自己给PhantomJS添加WebGL支持,不过,这个方案目前超出我的知识范围了,就没有继续研究。

    Puppeteer(chrome headless)

    Puppeteer是一个Node库,提供了控制chrome和chromium的API。默认运行headless模式,也支持界面运行。

    实现截屏的代码example.js:

    const puppeteer = require('puppeteer');
    
    (async () => {
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.setViewport({ // 设置视窗大小
        width: 600,
        height: 800
        });
        await page.goto('https://example.com'); // 打开页面
        await page.screenshot({path: 'example.png'}); // path: 截屏文件保存路径
    
        await browser.close();
    })();
    

    运行:

    node example.js
    

    接下来看下screenshot方法的实现原理:

    screenshot的源码位于lib/cjs/puppeteer/common/Page.js文件中,是一个异步方法:

    async screenshot(options = {}) {
        // ...
        return this._screenshotTaskQueue.postTask(() => this._screenshotTask(screenshotType, options));
    }
    async _screenshotTask(format, options) {
        // ...
        const result = await this._client.send('Page.captureScreenshot', {
        format,
        quality: options.quality,
        clip,
        });
        // ...
    }
    

    这个this._client.send又是个什么东西?别急,我们重新看下Puppeteer的定义:

    Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol.

    看到最后面那个DevTools Protocol了吗?这是个什么东西:

    The Chrome DevTools Protocol allows for tools to instrument, inspect, debug and profile Chromium, Chrome and other Blink-based browsers.

    详细的解释可以看这篇博客。

    简单来说,Puppeteer就是通过WebSocket给浏览器发送遵循Chrome Devtools Protocol的数据,命令浏览器去执行一些操作。然后,浏览器再通过WebSocket把结果返回给Puppeteer。这个过程是异步的,所以看源代码会发现好多async/await。

    所以screenshot方法是调用了Chrome Devtools Protocol的captureScreenshot。

    总结:

    1. 支持WebGL。

    2. 网页比较复杂的话,截屏时间也挺长的,我测试的页面是几百毫秒。

    3. Puppeteer是对(CDP)Chrome Devtools Protocol功能的封装。大部分功能都是通过WebSocket传输给CDP处理的。

    SlimerJS

    SlimerJS和PhantomJS类似。不同点是SlimerJS是基于火狐的浏览器引擎Gecko,而不是Webkit。

    SlimerJS可以通过npm安装,最新版本是1.x。不过兼容的火狐版本是53.0到59.0。我看现在火狐最新版本都82了。因为我本机是安装了火狐最新版本的,所以我还得安装一个老版本的火狐,比如59.0。可以参考这篇安装旧版本的火狐浏览器。我是mac系统,感觉安装还是挺容易的。

    实现截屏的代码screenshot.js:

    var page = require('webpage').create();
    page.open("http://slimerjs.org", function (status) {
        page.viewportSize = { width:1024, height:768 };
        page.render('screenshot.png');
    });
    

    运行

    // mac操作系统设置火狐路径
    export SLIMERJSLAUNCHER=/Applications/Firefox.app/Contents/MacOS/firefox
    ./node_modules/.bin/slimerjs screenshot.js // 我是局部安装的slimer包
    

    需要注意的是SLIMERJSLAUNCHER=/Applications/Firefox.app/Contents/MacOS/firefox启动的是火狐默认的安装路径,因为我一开始就有火狐浏览器,所以启动的是最新版本的浏览器,然后就报错了,说不兼容。在前面我安装过一个59版本的火狐,那么这个火狐浏览器的路径是什么?

    在应用程序里面我把这个旧版本的火狐命名为Firefox59,然后这个路径就是/Applications/Firefox59.app/Contents/MacOS/firefox。重新设置SLIMERJSLAUNCHER为59版本的火狐浏览器之后,发现就能成功了。

    不过,Puppeteer默认会打开浏览器界面,也就是non-headless模式。如果要使用headless模式,可以

        ./node_modules/.bin/slimerjs --headless screenshot.js
    

    不过,headless模式下,不支持WebGL。

    我在写例子的时候,发现的一个明显的不同就是Puppeteer截屏是异步函数,而SlimerJS截屏是同步函数?好奇心驱使下,看了下源码(src/modules/slimer-sdk/webpage.js):

    render: function(filename, options) {
        // ...
        let canvas = webpageUtils.getScreenshotCanvas(
        browser.contentWindow,
        finalOptions.ratio,
        finalOptions.onlyViewport, this);
        }
        canvas.toBlob(function(blob) {
        let reader = new browser.contentWindow.FileReader();
        reader.onloadend = function() {
            content = reader.result;
        }
        reader.readAsBinaryString(blob);
        }, finalOptions.contentType, finalOptions.quality);
        // ...
    }
    

    webpageUtils.getScreenshotCanvas(src/modules/webpageUtils.jsm):

    getScreenshotCanvas : function(window, ratio, onlyViewport, webpage) {
        // ...
        // create the canvas
        let canvas = window.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
        canvas.width = canvasWidth;
        canvas.height = canvasHeight;
    
        let ctx = canvas.getContext("2d");
        ctx.scale(ratio, ratio);
        ctx.drawWindow(window, clip.left, clip.top, clip.width, clip.height, "rgba(0,0,0,0)");
        ctx.restore();
    
        return canvas;
    }
    

    关键代码就是那行ctx.drawWindow。what?JS原生API还支持直接截屏?
    CanvasRenderingContext2D.drawWindow():只有火狐支持,已经被废弃掉的非规范定义的标准API。

    总结

    1. 1.0版本支持的火狐版本是53.0到59.0。不保证最新版本火狐可用。

    2. headless模式下,不支持WebGL。

    dom-to-image

    dom-to-image:前端截屏的开源库。工作原理是:
    SVG的foreignObject标签可以包裹任意的html内容。那么,为了渲染一个节点,主要进行了以下步骤:

    1. 递归地拷贝原始dom节点和后代节点;

    2. 把原始节点以及后代节点的样式递归的应用到对应的拷贝后的节点和后代节点上;

    3. 字体处理;

    4. 图片处理;

    5. 序列化拷贝后的节点,把它插入到foreignObject里面,然后组成一个svg,然后生成一个data URL;

    6. 如果想得到PNG内容或原始像素值,可以先使用data URL创建一个图片,使用一个离屏canvas渲染这张图片,然后从canvas中获取想要的数据。

    测试的时候,发现外部资源不能加载,所以简单的了解了后就放弃了。

    html2canvas

    html2canvas。网上查了下感觉有一篇文章写的挺好的:浅析 js 实现网页截图的两种方式。感兴趣的可以看下。

    未验证的猜想

    虽然后面这两种是前端的实现方式,但是结合前面讲的headless库,也是可以实现后端截屏的。以Puppeteer的API为例,可以首先使用page.addScriptTag(options)往网页中添加前端截屏的库,然后在page.evaluate(pageFunction[, ...args])中的pageFunction函数里面写相应的截屏代码就可以了,因为pageFunction的执行上下文是网页上下文,所以可以获取到document等对象

    专注分享当下最实用的前端技术。关注前端达人,与达人一起学习进步!

    长按关注"前端达人"

    展开全文
  • 功能: 基于web的实用屏幕截图工具,用于实现类似百度地图的截图功能,可自由拖动并对屏幕进行截图。 使用: 必须在页面body中设置一个最大的DIV,然后在config.js中设置设置该div的id。JDK1.5及其以上。源代码见附件...
  • js实现当前屏幕截图并另存为图片

    万次阅读 2018-10-19 15:34:02
    首先要用到 html2canvas 插件,这个插件... //保存数据,把当前报表的数据保存为Png图片,在触发另存为...的同时,指定文件名和文件格式 $('#saveData').click(function () { //#proMain:要截图的DOM元素 //useCO...
    首先要用到 html2canvas 插件,这个插件的作用是,把指定dom元素克隆一份,并转化为canvas
    //保存数据,把当前报表的数据保存为Png图片,在触发另存为...的同时,指定文件名和文件格式
            $('#saveData').click(function () {
                //#proMain:要截图的DOM元素
                //useCORS:true:解决跨域问题
                html2canvas(document.querySelector('#proMain'),{useCORS:true}).then(function (canvas) {
                    //获取年月日作为文件名
                    var timers=new Date();
                    var fullYear=timers.getFullYear();
                    var month=timers.getMonth()+1;
                    var date=timers.getDate();
                    var randoms=Math.random()+'';
                    //年月日加上随机数
                    var numberFileName=fullYear+''+month+date+randoms.slice(3,10);
                    var imgData=canvas.toDataURL();
                    //保存图片
                    var saveFile = function(data, filename){
                        var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
                        save_link.href = data;
                        save_link.download = filename;
    
                        var event = document.createEvent('MouseEvents');
                        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
                        save_link.dispatchEvent(event);
                    };
                    //最终文件名+文件格式
                    var filename = numberFileName + '.png';
                    saveFile(imgData,filename);
                    //document.body.appendChild(canvas);  把截的图显示在网页上
                })
            })

     

    展开全文
  • 在很多场合下,我们可能有这样的需求:提供个屏幕截图上传到系统,作为一个凭证。传统的操作方式是:屏幕截图,保存文件到本地,在web页面上选择本地文件并上传,这里至少需要三步。有没有可能直接将截图粘帖到web...
  • js 屏幕截图 dom-to-image

    2020-12-12 21:04:17
    dom-to-image github 简单示例 var node = document.body domtoimage.toPng(node).then(function (dataUrl) { var img = new Image(); img.src = dataUrl; document.body.appendChild(img); ...
  • 利用Google的“报告错误”或“反馈工具”,您可以选择浏览器窗口的区域来创建屏幕截图,并在屏幕上提交有关错误的反馈。 Jason Small的屏幕截图,张贴在一个重复的问题中 。 他
  • javaScript屏幕截图

    2021-05-08 16:46:09
    http://html2canvas.hertzen.com/
  • JQ JS javascript 截图功能 画图功能
  • 使用创建屏幕截图 安装 npm install nw-shot 用法 var fs = require ( 'fs' ) ; var screenshot = require ( 'nw-shot' ) ; screenshot ( { url : 'http://google.com' , width : 1024 , height : 768 } ) . pipe...
  • node puppeteer生成屏幕截图

    千次阅读 2019-03-21 10:19:53
    于是经过研究最后采用了node无头浏览器进行屏幕截图来实现 原文参考地址:原文连接 首先node环境如何搭建就不在这里说了 那么直接上图首先引入依赖的包 创建中间件,以及请求参数配置 接下来启动服务,监听端口 ...
  • JS截屏(页面转图片)插件 一、 PhantomJS PhantomJS Puppeteer(chrome headless) Puppeteer SlimerJS SlimerJS dom-to-image dom-to-image html2canvas html2canvas
  • 屏幕截图基于DOM,因此可能无法真实表示100%的准确度,因为它无法生成实际的屏幕截图,而是根据页面上可用的信息来构建屏幕截图。 订制 这是Erik Koopmans定制的版本,具有最新的错误修正和功能。 此处的所有更改...
  • 屏幕截图基于DOM,因此可能无法真实表示100%的准确度,因为它无法生成实际的屏幕截图,而是根据页面上的可用信息构建屏幕截图。 它是如何工作的? 该脚本通过读取DOM和应用于元素的不同样式,将当前页面呈现为...
  • 通过调取Js方法实现Unity WebGL 屏幕截屏(相机全屏)及下载成jpeg图片,demo文件测试时截图下载位置是浏览器默认下载路径,如要指定下载路径,打开浏览器设置的下载时询问下载地址即可。当前demo下载文件格式是jpg...
  • 屏幕截图是基于DOM的,因此,鉴于它不是实际的屏幕截图,而是基于页面的可用数据和信息构建的一种屏幕截图,因此对于实际表示而言,它可能不是100%准确。 该脚本通过读取DOM和特色元素的不同样式,将此类页面呈现...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,448
精华内容 8,179
关键字:

js屏幕截屏