Git Product home page Git Product logo

progressive-image's Introduction

progressive-image

A dead simple progressive-image module for Vanilla JavaScript and Vue.js 1.0+ & 2.0+

gif

GitHub

GitHub - progressive-image

NPM

NPM version

NPM - progressive-image

update

@v1.1.0

add the scale option for origin image animation

Install

$ npm install progressive-image --save
 
$ yarn add progressive-image

For Vanilla JS

demo

progressive-image-demo

progressive-image-vue-demo

Usage

import css

<link href="./node_modules/progressive-image/dist/index.css" rel="stylesheet" type="text/css">

or

<link href="//unpkg.com/progressive-image/dist/index.css" rel="stylesheet" type="text/css">

HTML

<main id="app">
  <div class="progressive">
    <img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/1.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r1.jpg" />
  </div>
  <div class="progressive">
    <img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/2.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg" />
  </div>
</main>
<script src="./dist/index.js"></script>

JS

(function(){
  new Progressive({
    el: '#app',
    lazyClass: 'lazy',
    removePreview: true
    scale: true
  }).fire()
})()

For Vue.js

import css

<link href="./node_modules/progressive-image/dist/index.css" rel="stylesheet" type="text/css">

or

<link href="//unpkg.com/progressive-image/dist/index.css" rel="stylesheet" type="text/css">

HTML

<main id="app">
  <template v-for="item in imgs">
    <div class="space"></div>
    <div class="progressive">
      <img class="preview" v-progressive="item.src" :data-srcset="item.srcset" :src="item.preview" />
    </div>
  </template>
</main>

JS

import Vue from 'vue'
import progressive from 'progressive-image/dist/vue'

Vue.use(progressive, {
  removePreview: true,
  scale: true
})

new Vue({
  name: 'demo',
  el: '#app',
  data: {
    imgs: [
      {
        src: 'http://7xiblh.com1.z0.glb.clouddn.com/progressive/2.jpg',
        preview: 'http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg'
      },
      {
        src: 'http://7xiblh.com1.z0.glb.clouddn.com/progressive/3.jpg',
        preview: 'http://7xiblh.com1.z0.glb.clouddn.com/progressive/r3.jpg'
      }
    ]
  }
})

build

build dist

npm run build

build demo

npm run demo

progressive-image's People

Contributors

avrahamappel avatar ccforward avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

progressive-image's Issues

图片加载不全,一部分一直保持模糊状态

我的vue项目遇到这样一个问题,同一个页面我用到两个v-progressive指令,分别有两个板块的图片,但是最多只能加载出一个屏幕区域的图片,其它图片就会一直保持模糊状态不在加载,请问这该怎么解决呢?

图片大小问题

可以限制模糊图片的大小,当真正的图片加载出来后大小就是图片大小不能调整高度,多张图片有滚动条时好像要向下滚动一下才能显示真正的图片

How to remove console output?

Hello. Thanks for the package!
I want to know what is the way to remove console log output? Not really nice to put this in production.

代码优化问题

看了下你的源代码,感觉在图片大小尺寸处理上这种做法不太优雅:通过加一个父节点通过父节点去控制图片的显示大小,这种做法有两个缺点

  • 一是这样呈现的图片大小并不是真正的图片大小,多多少少都会与真实的图片大小有差。
  • 二是代码结构并不太好,不适合用于真正的生产环境,如果在项目中使用你的这个解决方法,还需要在图片结果上按照你的去做修改,开发者可能使用体验上不好,就个人而言,希望可以只需要引入dist.js就可以使用了。

其他的,看了下知乎的做法,

  • 知乎貌似是直接讲图片宽高作为参数的,但如何获取到这个尺寸不知道他怎么实现的(可能是后台api做的工作吧)。
  • 知乎是用canvas实现的,这个项目是用blur实现的哈,个人比较喜欢你这种做法。
  • 缩放效果在有的时候感觉头有点晕晕的,如果可以,希望做成一个选项方式。

其他的

  • 看到你是有监听了很多事件“scroll', 'wheel', 'mousewheel', 'resize“,没有测试过性能方面的问题,但是感觉
    是否有点冗余,而且不够优雅。之前fork过一个可视化区域加载图片懒加载代码 https://github.com/rowthan/lazy-load-img 感觉他那种做法还挺不错的。

Will not work with any other library that uses the Array 'in' operator

In undex-vue.js you create a new array property 'remove' as enumerable property.

Array.prototype.remove = function(item) {
      if(!this.length) return
      const idx = this.indexOf(item);
      if(idx > -1) return this.splice(idx,1)
}

Because of this every Array will have a new property 'remove' with the function as value when getting the Array properties by:

for(x in array) {}

This breaks for examle jQuery ajaxForm and many other libraries.

Please declare the remove method as non enumerable:

Object.defineProperty(Array.prototype, 'remove', { 
    enumerable: false,
    value: function(item) {
      if(!this.length) return
      const idx = this.indexOf(item);
      if(idx > -1) return this.splice(idx,1)
    }

});

Sometimes I get an Uncaught DOMException error, and images are not load.

In general, plugin works. But a few times I had this error:

Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
    at Image.<anonymous> (http://calm-push.surge.sh/static/js/vendor.636071240149cb133e9f.js:33078:2858)

And only first image on page loaded, but only blurred preview.
Somebody notice this?

多余的console

使用这个插件, 会监听滚动事件一直有console输出, 以及初始化完成时, 也有一个console.

图片直接进行加载

按照作者的代码试了一下,发现图片(第二张和第三张)在没有滚动的情况下会自动加载出来,找不到原因

<main id="app">
  <div class="progressive">
    <img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/1.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r1.jpg"/>
  </div>
  <div class="space"></div>
  <div class="progressive">
    <img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/2.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg"/>
   </div>
   <div class="space"></div>
   <div class="progressive">
     <img class="preview lazy" data-src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/1.jpg" src="http://7xiblh.com1.z0.glb.clouddn.com/progressive/r2.jpg" />
   </div>
</main>
 class Progressive {
            constructor(option) {
                this.el = option.el
                this.lazyClass = option.lazyClass || 'lazy'
                this.removePreview = option.removePreview || false

                this.EVENTS = ['scroll', 'wheel', 'mousewheel', 'resize']
                this.Util = {
                    throttle(action, delay) {
                        let timeout = null
                        let lastRun = 0
                        return function () {
                            if (timeout) {
                                return
                            }
                            const elapsed = Date.now() - lastRun
                            const context = this
                            const args = arguments
                            const runCallback = function () {
                                lastRun = Date.now()
                                timeout = false
                                action.apply(context, args)
                            }
                            if (elapsed >= delay) {
                                runCallback()
                            } else {
                                timeout = setTimeout(runCallback, delay)
                            }
                        }
                    },
                    on(el, ev, fn) {
                        el.addEventListener(ev, fn)
                    },
                    off(el, ev, fn) {
                        el.removeEventListener(ev, fn)
                    }
                }

                this.windowHasBind = false

                this.lazy = this.Util.throttle(_ => {
                    this.fire()
                }, 300)

                this.animationEvent = this.getAnimationEvent()
            }

            fire() {
                if (!this.windowHasBind) {
                    this.windowHasBind = true
                    this.events(window, true)
                }

                const lazys = document.querySelectorAll(`${this.el} img.${this.lazyClass}`)
                const l = lazys.length
                if (l > 0) {
                    for (let i = 0; i < l; i++) {
                        const rect = lazys[i].getBoundingClientRect()
                        if (rect.top < window.innerHeight && rect.bottom > 0 && rect.left < window.innerWidth && rect.right > 0) {
                            this.loadImage(lazys[i])
                        }
                    }
                } else {
                    this.windowHasBind = false
                    this.events(window, false)
                }
            }

            events(el, bind) {
                if (bind) {
                    this.EVENTS.forEach(evt => {
                        this.Util.on(el, evt, this.lazy)
                    })
                } else {
                    this.EVENTS.forEach(evt => {
                        this.Util.off(el, evt, this.lazy)
                    })
                }
            }

            loadImage(item) {
                const img = new Image()
                if (item.dataset) {
                    item.dataset.srcset && (img.srcset = item.dataset.srcset)
                    item.dataset.sizes && (img.sizes = item.dataset.sizes)
                }
                img.src = item.dataset.src
                img.className = 'origin'
                item.classList.remove('lazy')
                img.onload = _ => {
                    this.mountImage(item, img)
                }
                img.onerror = _ => {
                    item.classList.add('lazy')
                }
            }

            getAnimationEvent() {
                const el = document.createElement('fake')
                const animations = {
                    "animation": "animationend",
                    "OAnimation": "oAnimationEnd",
                    "MozAnimation": "animationend",
                    "WebkitAnimation": "webkitAnimationEnd"
                }
                for (let a in animations) {
                    if (el.style[a] !== undefined) {
                        return animations[a]
                    }
                }
            }

            mountImage(preview, img) {
                const parent = preview.parentNode
                parent.appendChild(img).addEventListener(this.animationEvent, e => {
                    e.target.alt = preview.alt || ''
                    preview.classList.add('hide')
                    if (this.removePreview) {
                        parent.removeChild(preview)
                        e.target.classList.remove('origin')
                    }
                })
            }
        }
(function () {
  new Progressive({
    el: '#app',
    lazyClass: 'lazy', 
    removePreview: true
  }).fire();
})()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.